Python中有静态构造函数这样的东西吗?
如何在 Python 中实现静态构造函数?
这是我的代码...当我像这样调用应用程序时,
__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 对象都会被重新创建。 我的“真正的”应用程序课程很长。
我创建了一个
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
静态语言和动态语言之间存在根本区别,一开始并不总是显而易见。
在静态语言中,类是在编译时定义的,一切都很好,并且在程序运行之前就已具体设置。
在动态语言中,类实际上是在运行时定义的。 一旦解释器解析并开始执行所有这些类和 def 语句,就会运行静态构造函数的等效项。 此时正在执行类定义。
您可以在类体内的任何位置放置任意数量的语句,它们实际上是静态构造函数。 如果需要,您可以将它们全部放在不使用
self
作为参数的函数中,并在类末尾调用该函数。
提示:任何引用
self
的内容都需要该类的实例化。你可以这样做:
class App:
email_queue = EmailQueue()
App.email_queue.do_something()
但是拜托,这看起来像是很多废话。我使用 SLAks,只需在课堂外初始化它即可。或者,您可以查看单例模式。
您可以使用
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")
但是,请注意,这很可能是您不想要做的事情,因为它修改了type的状态 - 因此它将影响对该类型的使用/依赖于更改的方法的所有进一步调用静态类数据成员。如果在此类的实例中通过
self.
访问和设置此类静态类数据成员,情况可能会变得很糟糕,此时您很容易会出现意外行为。
真正正确的方法(或者大多数开发人员期望的行为的常识方法),是确保静态数据成员仅在导入期间设置一次(类似于静态数据成员的方式)初始化在 C++、C#、Java 中表现)。 Python 有这样的机制 - in-place初始化:
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()
您需要实例化您的应用程序,然后使用它:
myApp = App()
myApp.EmailQueue.DoSomething()
这是对这个问题的另一种看法,阐述了类 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] ) )
只是想根据@jxramos的答案分享似乎对我有用的东西
这里局部变量位于函数中,以避免删除它们:
class StaticClass():
numbers = []
@staticmethod
def static_init() -> []:
values = []
for i in range(1, 6):
values.append(i)
return values
numbers = static_init()