在Python中使用module作为类实例

Ray*_*Ray 5 python module class

TL; DR

基本上问题是关于向用户隐瞒我的模块具有类实现的事实,以便用户可以使用该模块,就像它具有类似的直接函数定义一样 my_module.func()

细节

假设我有一个模块my_module和一个MyThing存在于其中的类.例如:

# my_module.py

class MyThing(object):
    def say():
        print("Hello!")
Run Code Online (Sandbox Code Playgroud)

在另一个模块中,我可能会这样做:

# another_module.py

from my_module import MyThing

thing = MyThing()
thing.say()
Run Code Online (Sandbox Code Playgroud)

但是假设我不想那么做.我真正想要的是my_module自动创建MyThing实例,import以便我可以执行以下操作:

# yet_another_module.py

import my_module

my_module.say()
Run Code Online (Sandbox Code Playgroud)

换句话说,无论我在模块上调用什么方法,我都希望它直接转发到包含在其中的类的默认实例.因此,对于模块的用户来说,似乎它中没有类,只是模块本身中的直接函数定义(其中函数实际上是包含在其中的类的方法).那有意义吗?这样做有一个简短的方法吗?

我知道我可以做以下事情my_module:

class MyThing(object):
    def say():
        print("Hello!")

default_thing = MyThing()

def say():
    default_thing.say()
Run Code Online (Sandbox Code Playgroud)

但是假设MyThing我想要使​​用许多"公共"方法,那么我必须为每个方法明确定义一个"转发"函数,我不想这样做.

作为我上面的问题的扩展,有没有办法实现我想要的上面,但也能够使用代码,from my_module import *并能够MyThing直接在另一个模块中使用方法,如say()

Ant*_*ala 6

在模块中my_module执行以下操作:

class MyThing(object):
    ...

_inst = MyThing()
say = _inst.say
move = _inst.move
Run Code Online (Sandbox Code Playgroud)

正是random模块使用的模式.

自动执行此操作有点人为.首先,需要找出哪个实例/类属性是要导出的方法...也许只导出不能开头的名称_,比如

import inspect
for name, member in inspect.getmembers(Foo(), inspect.ismethod):
    if not name.startswith('_'):
        globals()[name] = member
Run Code Online (Sandbox Code Playgroud)

但是在这种情况下,我会说明确比隐含更好.