在Python中正确定义类变量的方法

353 投票
2 回答
487746 浏览
提问于 2025-04-17 11:54

我注意到在Python中,人们有两种不同的方式来初始化类的属性。

第一种方式是这样的:

class MyClass:
  __element1 = 123
  __element2 = "this is Africa"

  def __init__(self):
    #pass or something else

另一种风格看起来是这样的:

class MyClass:
  def __init__(self):
    self.__element1 = 123
    self.__element2 = "this is Africa"

那么,哪种方式是正确的来初始化类的属性呢?

2 个回答

23

我觉得这个例子很好地解释了这两种风格的区别:

james@bodacious-wired:~$cat test.py 
#!/usr/bin/env python

class MyClass:
    element1 = "Hello"

    def __init__(self):
        self.element2 = "World"

obj = MyClass()

print dir(MyClass)
print "--"
print dir(obj)
print "--"
print obj.element1 
print obj.element2
print MyClass.element1 + " " + MyClass.element2
james@bodacious-wired:~$./test.py 
['__doc__', '__init__', '__module__', 'element1']
--
['__doc__', '__init__', '__module__', 'element1', 'element2']
--
Hello
World
Traceback (most recent call last):
  File "./test.py", line 17, in <module>
    print MyClass.element2
AttributeError: class MyClass has no attribute 'element2'

element1 是和类绑定在一起的,而 element2 是和类的一个实例绑定在一起的。

744

这两种方式没有绝对的对错,它们只是类元素的两种不同类型:

  • __init__ 方法外面的元素是静态元素;它们属于整个类。
  • __init__ 方法里面的元素是对象的元素(self);它们不属于类。

看一些代码会更清楚:

class MyClass:
    static_elem = 123

    def __init__(self):
        self.object_elem = 456

c1 = MyClass()
c2 = MyClass()

# Initial values of both elements
>>> print c1.static_elem, c1.object_elem 
123 456
>>> print c2.static_elem, c2.object_elem
123 456

# Nothing new so far ...

# Let's try changing the static element
MyClass.static_elem = 999

>>> print c1.static_elem, c1.object_elem
999 456
>>> print c2.static_elem, c2.object_elem
999 456

# Now, let's try changing the object element
c1.object_elem = 888

>>> print c1.static_elem, c1.object_elem
999 888
>>> print c2.static_elem, c2.object_elem
999 456

正如你所看到的,当我们改变类元素时,两个对象都会受到影响。但当我们改变对象元素时,另一个对象却没有变化。

撰写回答