Pythonic初始化(复杂)静态数据成员的方法

Roe*_*ler 17 python class

我有一个具有复杂数据成员的类,我想保持"静态".我想用函数初始化一次.Pythonic如何是这样的:

def generate_data():
    ... do some analysis and return complex object e.g. list ...

class Coo:
    data_member = generate_data()
    ... rest of class code ...
Run Code Online (Sandbox Code Playgroud)

该函数generate_data需要很长时间才能完成并返回在正在运行的程序范围内保持不变的数据.每次Coo实例化时,我都不希望它运行.

此外,为了验证,只要我不指定任何东西data_member__init__,它仍将是"静态"?如果Coo中的方法附加一些值data_member(假设它是一个列表)会怎么样 - 这些添加是否可用于其他实例?

谢谢

Ric*_*dle 15

你是对的. data_member将被创建一次,并将可用于所有实例coo.如果任何实例修改它,则该修改将对所有其他实例可见.

这是一个演示所有这些的示例,其结果显示在最后:

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]
Run Code Online (Sandbox Code Playgroud)


dF.*_*dF. 14

正如其他人已经回答你是对的 - 我将再添加一件事要注意:如果实例修改了对象coo.data_member本身,例如

self.data_member.append('foo')
Run Code Online (Sandbox Code Playgroud)

然后其他实例看到修改.但是,如果你这样做

self.data_member = new_object
Run Code Online (Sandbox Code Playgroud)

然后创建一个新的实例成员,它覆盖类成员,只对该实例可见,而不是其他实例.差异并不总是很容易发现,例如self.data_member += 'foo'vs self.data_member = self.data_member + 'foo'..

为避免这种情况,您可能应始终将对象称为coo.data_member(不是通过self).


Jas*_*siu 6

data_member = generate_data()执行时,该语句只执行一次class coo: ....在大多数情况下,类语句发生在模块级别,并在导入模块时执行.因此data_member = generate_data(),当您coo第一次使用类导入模块时,只会执行一次.

所有coo类的实例都将共享data_member并可以通过编写访问它coo.data_member.coo.data_member任何coo实例都可以立即看到所做的任何更改.实例可以拥有自己的data_member属性.可以通过键入来设置此属性,该属性self.data_member = ...仅对该实例可见.data_member仍可通过键入来访问"静态" coo.data_member.