我正在使用
Python 2.7
我想知道在Python OOP中是否可以在模块级别添加代码来初始化模块中包含的类.
class DoSomething(object):
foo = 0
bar = 0
@classmethod
def set_all_to_five(cls):
cls.bar = 5
cls.foo = 5
@classmethod
def set_all_to_ten(cls):
cls.bar = 10
cls.foo = 10
#Module level code - runs on import of the class DoSomething
DoSomething.set_all_to_five()
输出:
>>> from productX.moduleY import DoSomething
>>> print DoSomething.bar
5
该类只包含@classmethod方法,因此我可以调用它们而无需实例化该类.
模块级代码DoSomething.set_all_to_5()在导入模块时初始化类级属性.
最佳答案
[It it] OK to add code in the module level to initialize a class that is contained in the module?
是的,你拥有的很好.当人们将Python描述为动态语言时,这就是“dynamic”这个词的含义:您可以在运行时更改类型的定义.定义类的整个模块必须在可以使用DoSomething名称之前成功导入,因此不可能有人意外使用该类的“未修补”版本.
但是,如果您希望在类块中完全定义类的行为,而不是在类定义之后应用“monkeypatch”,则可以使用其他一些选项.
使用元类:
class DoSomethingMeta(type):
def __init__(self, name, bases, attrs):
super(DoSomethingMeta, self).__init__(name, bases, attrs)
self.set_all_to_five()
class DoSomething(object):
__metaclass__ = DoSomethingMeta # for Python3, pass metaclass kwarg instead
foo = 0
bar = 0
@classmethod
def set_all_to_five(cls):
cls.bar = 5
cls.foo = 5
@classmethod
def set_all_to_ten(cls):
cls.bar = 10
cls.foo = 10
或者,更简单地说,通过使用装饰器:
def mydecorator(cls):
cls.set_all_to_five()
return cls
@mydecorator
class DoSomething(object):
....