python collections namedtuple模块的迷思

赋值覆盖不了的问题

from collections import namedtuple

# namedtuple('名称', [属性list]):
Point = namedtuple('Point', ['x', 'y', 'z'])
p = Point('x', 'y', 'z')
print(p)
Point.x=8
p=Point(4,3,2)
print(p.x, p.y, p.z,p)

img


结果跟想像的不一样
用Point.x来赋值就把p.x的值锁定住了
再用p=Point()来赋值就覆盖不掉了

看了namedtuple的源码,大概知道是怎么回事了。。。
单看下面这段

    for index, name in enumerate(field_names):
        try:
            itemgetter_object, doc = cache[index]
        except KeyError:
            itemgetter_object = _itemgetter(index)
            doc = f'Alias for field number {index}'
            cache[index] = itemgetter_object, doc
        class_namespace[name] = property(itemgetter_object, doc=doc)

    result = type(typename, (tuple,), class_namespace)

题中p = Point(4, 3, 2)创建时,p.x, p.y和p.z并非实例属性,而是Point中修饰过的property object
大概意思就是求p.x时,该方法继承于Point,调用Point.x,即返回传入p的第0个对象,当Point.x被赋值为8后,p.x的调用仍按此路线走,所以返回了8,造成类属性覆盖实例属性的现象


from collections import namedtuple
# namedtuple('名称', [属性list]):
Point = namedtuple('Point', ['x', 'y', 'z'])
p = Point('x', 'y', 'z')
print(p)
class P:
    def __init__(self,x,y,z):
        self._x=x
        self._y=y
        self._z=z
        global p
        p = Point(x, y, z)
    @property
    def x(self):
        pass
    @x.setter
    def x(self,x):
        self._x=x
        Point.x=x
        global p
        p = Point(x, self._y, self._z)
    @property
    def y(self):
        pass
    @y.setter
    def y(self,y):
        self._y=y
        Point.y=y
        global p
        p = Point(self._x, y,self._z)
    @property
    def z(self):
        pass
    @z.setter
    def z(self,z):
        self._z=z
        Point.z=z
        global p
        p = Point(self._x,self._y, z)
b=P(2,3,4)
print(p)
b.x=3
print(p)
b.y=5
print(p)
b.z=1
a=(p.x,p.y,p.z)
print(p,a)

提的问题不太好就自问自答了,
前段时间在b站上看到的装饰启@property
这个只能装饰类的私有变量
变量前面加个下滑线的就是私有变量

这个装饰器的作用是把类函数括号换成等号来赋值.
@property装饰完成后
@name.setter来定义可以用等号来赋值的函数,
用类的初始化来统一三个值
通过调用类函数来协调p与Point.x....的统一性

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632