python 初始化(复杂)静态数据成员的 Pythonic 方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/872973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pythonic Way to Initialize (Complex) Static Data Members
提问by Roee Adler
I have a class with a complex data member that I want to keep "static". I want to initialize it once, using a function. How Pythonic is something like this:
我有一个包含复杂数据成员的类,我想保持“静态”。我想使用一个函数将它初始化一次。Pythonic 是这样的:
def generate_data():
... do some analysis and return complex object e.g. list ...
class Coo:
data_member = generate_data()
... rest of class code ...
The function generate_data
takes a long while to complete and returns data that remains constant in the scope of a running program. I don't want it to run every time class Coo is instantiated.
该函数generate_data
需要很长时间才能完成并返回在运行程序范围内保持不变的数据。我不希望它在每次实例化 Coo 类时运行。
Also, to verify, as long as I don't assign anything to data_member
in __init__
, it will remain "static"? What if a method in Coo appends some value to data_member
(assuming it's a list) - will this addition be available to the rest of the instances?
另外,为了验证,只要我不给data_member
in分配任何东西__init__
,它就会保持“静态”?如果 Coo 中的一个方法向data_member
(假设它是一个列表)附加一些值怎么办- 这个添加是否可用于其余实例?
Thanks
谢谢
采纳答案by RichieHindle
You're right on all counts. data_member
will be created once, and will be available to all instances of coo
. If any instance modifies it, that modification will be visible to all other instances.
你在所有方面都是对的。 data_member
将被创建一次,并且可用于coo
. 如果任何实例对其进行了修改,则该修改将对所有其他实例可见。
Here's an example that demonstrates all this, with its output shown at the end:
这是一个演示所有这些的示例,其输出显示在最后:
def generate_data():
print "Generating"
return [1,2,3]
class coo:
data_member = generate_data()
def modify(self):
self.data_member.append(4)
def display(self):
print self.data_member
x = coo()
y = coo()
y.modify()
x.display()
# Output:
# Generating
# [1, 2, 3, 4]
回答by dF.
As others have answered you're right -- I'll add one more thing to be aware of: If an instance modifies the object coo.data_member
itself, for example
正如其他人回答的那样,你是对的——我会再添加一件要注意的事情:例如,如果一个实例修改了对象coo.data_member
本身
self.data_member.append('foo')
then the modification is seen by the rest of the instances. However if you do
然后修改被其余的实例看到。但是,如果你这样做
self.data_member = new_object
then a new instancemember is created which overrides the class member and is only visible to that instance, not the others. The difference is not always easy to spot, for example self.data_member += 'foo'
vs. self.data_member = self.data_member + 'foo'
.
然后创建一个新的实例成员,该成员覆盖类成员,并且仅对该实例可见,对其他实例不可见。差异并不总是很容易发现,例如self.data_member += 'foo'
vs. self.data_member = self.data_member + 'foo'
.
To avoid this you probably should always refer to the object as coo.data_member
(not through self
).
为了避免这种情况,您可能应该始终将对象称为coo.data_member
(而不是通过self
)。
回答by Jasiu
The statement data_member = generate_data()
will be executed only once, when class coo: ...
is executed. In majority of cases class statements occur at module level and are executed when module is imported. So data_member = generate_data()
will be executed only once when you import module with class coo
for the first time.
该语句data_member = generate_data()
将只执行一次,whenclass coo: ...
被执行。在大多数情况下,类语句出现在模块级别并在导入模块时执行。所以data_member = generate_data()
当你coo
第一次用类导入模块时只会执行一次。
All instances of coo
class will share data_member
and can access it by writing coo.data_member
. Any changes made to coo.data_member
will be immediately visible by any coo
instance. An instance can have its own data_member
attribute. This attribute can be set by typing self.data_member = ...
and will be visible only to that instance. The "static" data_member
can still be accessed by typing coo.data_member
.
coo
类的所有实例都将共享data_member
并可以通过编写coo.data_member
. 对coo.data_member
任何coo
实例所做的任何更改都将立即可见。一个实例可以有它自己的data_member
属性。此属性可以通过键入来设置,self.data_member = ...
并且仅对该实例可见。“静态”data_member
仍然可以通过键入访问coo.data_member
。