如何解决整齐地实例化模块内的类
编辑:我想通了,如果这被标记为不是重复,我会很感激,因为它不是,通过保持 __init__.py 为空,我有效地创建了一个我想成为主模块的子模块。将一些关键内容移至 __init__.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 举报,一经查实,本站将立刻删除。