7

我来自 C++ 背景到 python

我一直在声明成员变量并以 C++esqe 方式设置它们,如下所示:

class MyClass:
    my_member = []

    def __init__(self,arg_my_member):
        self.my_member = arg_my_member

然后我注意到在一些开源代码中,初始声明my_member = []被完全省略了,只在构造函数中创建。

这显然是可能的,因为 python 是动态的。

我的问题是,这是首选的还是 Pythonic 的做事方式,两者都有优缺点吗?

4

4 回答 4

9

您这样做的方式意味着您现在将拥有一个同名的“静态”成员和一个“非静态”成员。

class MyClass:
    my_member = []

    def __init__(self, arg_my_member):
        self.my_member = arg_my_member


>>> a = MyClass(42)
>>> print a.my_member
42
>>> print MyClass.my_member
[]
于 2010-07-24T10:35:00.530 回答
4

如果你在类中定义它,那么它是一个类变量,如果你在构造函数中定义它,它是一个对象变量。因此,如果您未在构造函数中定义它,则该类的所有实例都共享相同的类变量。

于 2010-07-24T10:31:11.053 回答
1

这两种方式对于 python 都是可以接受的,除非是可变值。当您像在示例中那样声明它时,您会得到非常意想不到的结果:

>>> class MyClass:
...     my_member = []
... 
>>> A = MyClass()
>>> B = MyClass()
>>> A.my_member.append(1)
>>> A.my_member
[1]
>>> B.my_member.append(2)
>>> B.my_member
[1, 2]
>>> A.my_member
[1, 2]
>>> MyClass.my_member
[1, 2]

由于类成员只生成一次,当类本身在模块加载时被处理时。如果您的成员打算在实例范围内使用,则应将其设置为__init__

不可变的值很好。

于 2010-07-24T11:15:12.150 回答
0

这将创建一个名为 my_member 的类属性

class MyClass:
    my_member = []

如果实例没有名为 my_member 的实例变量,则所有实例都可以通过self.my_member.

由于您正在创建一个名为的实例变量my_member,因此很可能从未使用过类变量,这只是混淆的标志

于 2010-07-24T10:33:09.160 回答