Python 类中的类属性遮蔽[重复]

2023-11-25

我正在学习this and this了解类属性。但对以下代码片段的输出感到困惑。

class A:
    aliases = None
    name = None

    def __init__(self,name):
        self.name = name
        self.aliases = set([name])

    def add_aliases(self,a):
        self.aliases.add(a)

    def __repr__(self):
        return str(self.name) + str(self.aliases)

arr = []
for i in range(3):
    arr.append(A(i))
    arr[-1].add_aliases(i+1)

for item in arr:
    print item

A.aliases = set([]) ##Modify the static element of class
for item in arr:
    print item  

Python解释器:2.7.9

输出是

0set([0, 1])
1set([1, 2])
2set([2, 3])
0set([0, 1])
1set([1, 2])
2set([2, 3])

我期待这样的输出。

0set([2, 3])
1set([2, 3])
2set([2, 3])
0set([])
1set([])
2set([])

解释是当我们写self.aliases = set([])我们实际上是creating a new实例属性,隐藏类属性.

所以,如果我们让我们的__init__函数如下,我们得到预期的输出。

def __init__(self,name):
    self.name = name
    A.aliases = set([name])  #using the class attribute directly

另请考虑以下代码片段:

class A:
    aliases = set([])
    name = None

    def __init__(self,name):
        self.name = name
        self.aliases.add(name) # using the class attribute indirectly.

    def add_aliases(self,a):
        self.aliases.add(a)

    def __repr__(self):
        return str(self.name) + str(self.aliases)

因为在这种情况下,我们not创建一个实例属性,没有阴影。问题中的测试代码将产生以下输出:

0set([0, 1, 2, 3])
1set([0, 1, 2, 3])
2set([0, 1, 2, 3])
0set([])
1set([])
2set([])

这是预期的,因为类属性在所有实例之间共享。

Here A.alias也可以称为self.alias inside init或任何其他功能。由于它没有隐藏静态属性,所以给出了预期的输出——所有对象共享一个公共属性的情况。

不了解这个概念的人在使用不可变数据结构(例如string等等。但是对于像这样的数据结构list and dictionary这可能会令人惊讶。

还请考虑以下定义init.

def __init__(self,name):
    self.name = name
    self.aliases.add(name) # referring to class attribute
    self.aliases = set([]) # creating a instance attribute

这个案例也最终导致了instance attribute测试代码产生的输出是:

0set([1])
1set([2])
2set([3])
0set([1])
1set([2])
2set([3])

从这一切中我学到的是:

始终使用类名称引用类属性,使用对象名称引用实例属性,即写A.aliases当你指的是类属性时aliases,不写self.aliases间接提及self.aliases

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 类中的类属性遮蔽[重复] 的相关文章

随机推荐