赋值覆盖不了的问题
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)
看了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....的统一性