Python中是否存在静态构造函数?
如何在Python中实现静态构造函数?
这是我的代码......当我像这样调用App时,__init__
不会触发。 __init__
不是静态构造函数或静态初始化程序。
App.EmailQueue.DoSomething()
我必须像这样调用它,每次都实例化App类:
App().EmailQueue.DoSomething()
这是我的班级:
class App:
def __init__(self):
self._mailQueue = EmailQueue()
@property
def EmailQueue(self):
return self._mailQueue
每次调用__init__
的问题是重新创建App对象。我的“真正的”App类很长。
答案 0 :(得分:21)
静态和动态语言之间存在根本区别,起初并不总是很明显。
在静态语言中,类是在编译时定义的,并且在程序运行之前一切都很好并且具体设置。
在动态语言中,类实际上是在运行时定义的。一旦解释器解析并开始执行所有这些类和def语句,就会运行等效的静态构造函数。此时正在执行类定义。
您可以在类体内的任何位置放置任意数量的语句,它们实际上是一个静态构造函数。如果需要,可以将它们全部放在不以self
作为参数的函数中,并在类的末尾调用该函数。
答案 1 :(得分:16)
提示:引用self
的任何内容都需要对类进行实例化。你可以这样做:
class App:
email_queue = EmailQueue()
App.email_queue.DoSomething()
但是来吧,这似乎有很多毛病。我喜欢SLaks,只是在课外初始化它。或者,您可以查看singleton pattern。
答案 2 :(得分:6)
我创建了一个static_init
装饰器,该装饰器将调用static_init
类方法(如果存在)。
这是装饰器,以及如何使用它来初始化枚举类的类变量的示例:
# pylint: disable=missing-docstring,no-member
import enum
def static_init(cls):
if getattr(cls, "static_init", None):
cls.static_init()
return cls
@static_init
class SomeEnum(enum.Enum):
VAL_A = enum.auto()
VAL_B = enum.auto()
VAL_C = enum.auto()
VAL_D = enum.auto()
@classmethod
def static_init(cls):
text_dict = {}
setattr(cls, 'text_dict', text_dict)
for value in cls:
text_dict[value.name.lower().replace("_", " ").title()] = value
def test_static_init():
assert SomeEnum.text_dict["Val A"] == SomeEnum.VAL_A
assert SomeEnum.text_dict["Val B"] == SomeEnum.VAL_B
assert SomeEnum.text_dict["Val C"] == SomeEnum.VAL_C
assert SomeEnum.text_dict["Val D"] == SomeEnum.VAL_D
答案 3 :(得分:2)
您需要实例化您的应用,然后使用它:
myApp = App()
myApp.EmailQueue.DoSomething()
答案 4 :(得分:1)
您可以使用class
方法-参见下面的代码示例中的@classmethod
装饰器:
class A(object):
_some_private_static_member = None
@classmethod
def reset_static_data_members(cls, some_value):
cls._some_private_static_member = some_value
A.reset_static_data_members("some static value")
但是请注意,这很可能是您不想想要做的事情,因为它会修改类型的状态-因此会影响以后所有对使用/依赖于更改后的静态类数据成员的那种类型的方法。如果在此类的实例中通过self.
访问并设置了此类静态类数据成员,当您很容易得到意外的行为时,情况就变得很糟糕。
真正做到这一点的正确方法(或大多数开发人员期望行为的常识方法)是确保仅一次设置静态数据成员-导入期间(静态数据成员初始化在C ++,C#,Java中的类比方式)。 Python具有实现该功能的机制-就地初始化:
class A(object):
_some_private_static_member_0 = "value 0"
_some_private_static_member_1 = "value 1"
可能您可以使用从函数中返回的值初始化静态类成员,这些函数从(类中)抽象出更复杂的值生成:
class A(object):
_some_private_static_member_0 = some_function_0()
_some_private_static_member_1 = some_function_1()
答案 5 :(得分:0)
这是对此问题的另一种看法,在类def之后和任何类函数之前阐述代码区域。我将if条件和代码折叠区域括起来,以便各种编辑器能够在您想要隐藏它的情况下折叠这段代码....
class MyClass :
myStaticVar1 = {}
myStaticVar2 = []
#region STATICINIT
if not myStaticVar1 :
# implement arbitrary initialization logic here
# with any helper variables you don't want cluttering up the class
localVarDontWantInClassScope = [1,2,3]
myStaticVar1[0] = localVarDontWantInClassScope[0]
myStaticVar1[1] = localVarDontWantInClassScope[2]
myStaticVar2.append("abc")
# local var cleanup
del localVarDontWantInClassScope
#endregion
def f1(self, i) :
print( "{} {}".format( i , MyClass.myStaticVar1[i] ) )