Python 3 - 直接操作 class' 属性是否会覆盖其对象的相同属性,从而使属性成为纯静态的? [解决了]
Python 3 - Does the direct manipulation of a class' attribute override the same attribute for its objects making the attribue purely static? [SOLVED]
在了解 classes 在 Python 中的工作原理时,我遇到了一个 class 定义示例,它在我看来有点奇怪。
该示例的目的是演示如何在 Python 中实现静态变量的行为。例子是这样写的:
class MemberCounter:
members = 0
def init(self):
MemberCounter.members += 1
m1 = MemberCounter()
m1.init()
m2 = MemberCounter()
m2.init()
设置 class 并创建对象后,我打印了 'members' 属性的值。这些是结果:
MemberCounter.members = 2
m1.members = 2
m2.members = 2
那是我感到困惑的时候。当我期待 'MemberCounter.members = 2' 时,其他两个结果对我来说毫无意义 - 为什么 'm1' 和 'm2' 对象的 'members' 值都等于 2?我认为这两个值都应该是 0 - 如果被更改的唯一属性是附加到 MemberCounter class 的 'members' 属性,为什么它会导致对自己的唯一 'members' 每个 class' 对象的值。看起来 'members' 属性在每个对象的 init() 函数中的地址类似于 'MemberCounter.members += 1',完全覆盖了 m1.members[=54 的唯一值=] 和 m2.members 引用并将它们的指针重定向到 MemberCounter.members 值,使所有三个指针都指向相同的值
==> m1.members = m2.members = MemberCounter.members.
此外,我尝试以相反的方式定义 class(增加 self.members 而不是 MemberCounter.members ):
class MemberCounter:
members = 0
def init(self):
self.members += 1
m1 = MemberCounter()
m1.init()
m2 = MemberCounter()
m2.init()
这个定义产生了合乎逻辑的结果(这让我对上面提到的奇怪行为更加好奇):
MemberCounter.members = 0
m1.members = 1
m2.members = 1
简而言之,我很好奇为什么第一个 class 定义的行为如此奇怪?为什么仅仅'MemberCounter.members += 1'语句就完全删除了'm1.members'和'm2.members' 拥有独特的价值,并使其等于 MemberCounter.members 价值。
我希望我能够清楚地提出我的问题,我将非常高兴能深入了解这种奇怪的行为:)
您可以 读取 带有 instance.attribute
符号的静态属性作为更自然的 class.attribute
符号的替代,是 [=34 中的预期功能=].
Both static data and static methods (in the sense of C++ or Java) are supported in Python.
For static data, simply define a class attribute. To assign a new
value to the attribute, you have to explicitly use the class name in
the assignment:
class C:
count = 0 # number of times C.__init__ called
def __init__(self):
C.count = C.count + 1
def getcount(self):
return C.count # or return self.count
c.count
also refers to C.count
for any c
such that
isinstance(c, C)
holds, unless overridden by c
itself or by some
class on the base-class search path from c.__class__
back to C
.
Caution: within a method of C
, an assignment like self.count = 42
creates a new and unrelated instance named “count” in self
’s own dict.
Rebinding of a class-static data name must always specify the class
whether inside a method or not:
C.count = 314
第一个代码块下方的段落解释了您的疑虑。 “注意”段落解释了您发现的合乎逻辑的内容。
在了解 classes 在 Python 中的工作原理时,我遇到了一个 class 定义示例,它在我看来有点奇怪。
该示例的目的是演示如何在 Python 中实现静态变量的行为。例子是这样写的:
class MemberCounter:
members = 0
def init(self):
MemberCounter.members += 1
m1 = MemberCounter()
m1.init()
m2 = MemberCounter()
m2.init()
设置 class 并创建对象后,我打印了 'members' 属性的值。这些是结果:
MemberCounter.members = 2
m1.members = 2
m2.members = 2
那是我感到困惑的时候。当我期待 'MemberCounter.members = 2' 时,其他两个结果对我来说毫无意义 - 为什么 'm1' 和 'm2' 对象的 'members' 值都等于 2?我认为这两个值都应该是 0 - 如果被更改的唯一属性是附加到 MemberCounter class 的 'members' 属性,为什么它会导致对自己的唯一 'members' 每个 class' 对象的值。看起来 'members' 属性在每个对象的 init() 函数中的地址类似于 'MemberCounter.members += 1',完全覆盖了 m1.members[=54 的唯一值=] 和 m2.members 引用并将它们的指针重定向到 MemberCounter.members 值,使所有三个指针都指向相同的值
==> m1.members = m2.members = MemberCounter.members.
此外,我尝试以相反的方式定义 class(增加 self.members 而不是 MemberCounter.members ):
class MemberCounter:
members = 0
def init(self):
self.members += 1
m1 = MemberCounter()
m1.init()
m2 = MemberCounter()
m2.init()
这个定义产生了合乎逻辑的结果(这让我对上面提到的奇怪行为更加好奇):
MemberCounter.members = 0
m1.members = 1
m2.members = 1
简而言之,我很好奇为什么第一个 class 定义的行为如此奇怪?为什么仅仅'MemberCounter.members += 1'语句就完全删除了'm1.members'和'm2.members' 拥有独特的价值,并使其等于 MemberCounter.members 价值。
我希望我能够清楚地提出我的问题,我将非常高兴能深入了解这种奇怪的行为:)
您可以 读取 带有 instance.attribute
符号的静态属性作为更自然的 class.attribute
符号的替代,是 [=34 中的预期功能=].
Both static data and static methods (in the sense of C++ or Java) are supported in Python.
For static data, simply define a class attribute. To assign a new value to the attribute, you have to explicitly use the class name in the assignment:
class C: count = 0 # number of times C.__init__ called def __init__(self): C.count = C.count + 1 def getcount(self): return C.count # or return self.count
c.count
also refers toC.count
for anyc
such thatisinstance(c, C)
holds, unless overridden byc
itself or by some class on the base-class search path fromc.__class__
back toC
.Caution: within a method of
C
, an assignment likeself.count = 42
creates a new and unrelated instance named “count” inself
’s own dict. Rebinding of a class-static data name must always specify the class whether inside a method or not:
C.count = 314
第一个代码块下方的段落解释了您的疑虑。 “注意”段落解释了您发现的合乎逻辑的内容。