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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:01:45  来源:igfitidea点击:

Pythonic Way to Initialize (Complex) Static Data Members

pythonclass

提问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_datatakes 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_memberin __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_memberin分配任何东西__init__,它就会保持“静态”?如果 Coo 中的一个方法向data_member(假设它是一个列表)附加一些值怎么办- 这个添加是否可用于其余实例?

Thanks

谢谢

采纳答案by RichieHindle

You're right on all counts. data_memberwill 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_memberitself, 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 coofor the first time.

该语句data_member = generate_data()将只执行一次,whenclass coo: ...被执行。在大多数情况下,类语句出现在模块级别并在导入模块时执行。所以data_member = generate_data()当你coo第一次用类导入模块时只会执行一次。

All instances of cooclass will share data_memberand can access it by writing coo.data_member. Any changes made to coo.data_memberwill be immediately visible by any cooinstance. An instance can have its own data_memberattribute. This attribute can be set by typing self.data_member = ...and will be visible only to that instance. The "static" data_membercan 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