我正在开发一个与另一个模块一起使用的模块。另一个模块要求在__init__
方法之前设置类属性(假定该另一个模块的行为无法更改,让我们开始工作)。这些类属性(在下面的示例中为Signal
)部分源自我代码中的对象。
以下所示的方法由于许多原因而成为灾难。例如,
my_obj1
和my_obj2
不保证存在;的
在这种情况下,导入其他模块将失败。 OtherModuleVodoo1
使用我代码中的2个不同实例
(my_obj
。这是解释代码的骨架:
import Signal, Device
from my_module.setup import my_obj1, my_obj2
class OtherModuleVodoo1(Device):
# The class signal attributes must be defined before the __init__
# and rely upon an object from my module
x = Signal(my_obj1.cmds['thing_x'], 'thing_x')
y = Signal(my_obj1.cmds['thing_y'], 'thing_y')
# ...
# ...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class OtherModuleVodoo2(Device):
x = Signal(my_obj2, 'thing1')
y = Signal(my_obj2, 'thing2')
# ...
# ...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# now in my file I do this
dev1 = OtherModuleVodoo1()
dev2 = OtherModuleVodoo2()
# but would much prefer to do this
dev1 = OtherModuleVodoo(my_object_input = my_obj1)
# where I don't need ```Vodoo1, Vodoo2``` but can have a generic
solution.
是否可以将参数“输入”到类的构造中(而不是类实例的初始化)?
__new__
,但这不会填充类定义中的名称空间(在__init__
之前)my_obj1 = None
直到需要一个OtherModuleVodoo1
实例,然后在实例化对象之前修改class属性:尝试3的示例:
xyq = None
class Test2():
print(xyq)
def __init__(self):
print(self.xyq)
Test2.xyq = 55
t2 = Test2()
但是,这里的输出是:
None
55
我期望完全集中于改变方法的回应。那是必要的。但是,我的直接问题是如何最好地使用创可贴。
答案 0 :(得分:1)
这可能需要一些按摩才能使其与您的代码一起使用,但是您可以在父类中使用__init_subclass__
来接受创建类的参数。这是在Python 3.6中引入的
class Voodoo:
def __init_subclass__(cls, myobj, **kwargs):
super().__init_subclass__(**kwargs)
cls.x = Signal(my_obj1.cmds['thing_x'], 'thing_x')
cls.y = Signal(my_obj1.cmds['thing_y'], 'thing_y')
class Voodoo1(Voodoo, Device, myobj=myobj1):
pass
您还可以将Voodoo
设为Device
的子类,以清理子类的签名。
答案 1 :(得分:0)
在Python 3中具有元类的示例
class Meta(type):
def __new__(cls, name, bases, dct):
dct['xyq'] = 55
return super().__new__(cls, name, bases, dct)
class A(metaclass=Meta):
... # A.xyq == 55
class B(A):
... # B.xyq == A.xyq == 55
当创建类A和B(不是实例化)时,元类才起作用。