微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

整齐地实例化模块内的类

如何解决整齐地实例化模块内的类

编辑:我想通了,如果这被标记为不是重复,我会很感激,因为它不是,通过保持 __init__.py 为空,我有效地创建了一个我想成为主模块的子模块。将一些关键内容移至 __init__.py 解决了我的问题。

我有一个 python 模块,expecter.py

class expecter():
    def __init__(self,host,username,password):
        # connect to host,setup typical ssh expect things
    def dothingstohost(self):
        self.sendcommandsandthings('etc')

像这样的 setup.py(假设项目没有子目录,只有一个 expecter.py 文件

from setuptools import setup

setup(
    name='expecter',version='1.21',packages=['.',],install_requires=[
        "pexpect",)

我想这样称呼它

import expecter

connection = expecter('someserver','someuser','somepass')

但是,在尝试了很多事情之后,我一直陷入这样一种情况:在 pip 安装之后,我必须像这样称呼它 connection = expecter.expecter('blahblah')。或者 pip 不喜欢我定义包的方式,它会感到困惑。我曾经只是将这个类与我的其他项目放在一起,但它变得越来越大,我正试图将它分离到它自己的项目中。

解决方法

这些都不是真正可取的;生态系统期望当他们导入一个模块时,他们会得到那个模块,而不是其他一些被黑掉的对象。像 from expecter import Expecter 这样的语句并不是糟糕的 Python 代码。也就是说,我们可以使导入系统按预期运行。

当您 import expecter 时,结果是 expecter 模块。为了能够调用它,您需要 模块本身 是可调用的。它们通常不是,所以我们想找到一些方法来改变它。

如果对象的类型实现了 __call__,则对象是可调用的。大多数内置类型都不容易被猴子修补,但在 3.5+ 中,您可以像其他任何对象一样修改模块。所以,这就是我们要做的 :) 此处的解决方案 was adapted from elsewhere on StackOverflow 并根据需要将您的 expecter 模块的类替换为定义了 __call__ 的类。

import sys

class Expecter:
    pass  # do your ssh voodoo here

class __CallableModuleHack(sys.modules[__name__].__class__):
    def __call__(self,*args,**kwargs):
        return Expecter(*args,**kwargs)

sys.modules[__name__].__class__ = __CallableModuleHack

另一种选择(灵感来自@martineau 的评论)是用具有所需行为的假模块替换整个模块。这应该至少适用于 Python 2.7+。

import sys,types

class Expecter:
    pass  # do your ssh voodoo here

class __FauxModule(types.ModuleType):
    def __init__(self):
        super().__init__(__name__)
        self.__dict__.update(sys.modules[__name__].__dict__)

    def __call__(self,**kwargs)

# so that the module containing our class isn't deleted
__ref = sys.modules[__name__]

sys.modules[__name__] = __FauxModule()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。