我已经实现了一个示例类PointLocation,
import collections as _collections
Point = _collections.namedtuple("Point", ("x", "y", "z"))
class PointLocation(object):
def __init__(self, x, y, z):
self._x = x
self._y = y
self._z = z
self._location = Point(x, y, z)
print "First Item: %s " % self._location[0]
def __repr__(self):
return "%s(%r, %r, %r)" % (
self.__class__.__name__,
self._x,
self._y,
self._z,
)
def __getitem__(self, key):
"""
to make the object to be used in a manner similar to a tuple or list
"""
return self._location.__getitem__(key)
def __setitem__(self, key, value):
if key == 0:
self._location = Point(self._location.x, value)
else:
self._location = Point(value, self._location.y)
我试图使用:
设置参数 x 的值 pointLocationObj[0] = 1
但我一直收到错误
Traceback (most recent call last):
File "/usr/san/Desktop/testScripts/classObject_returnsList.py", line 40, in <module>
pointLocationObj[0] = 7
File "/usr/san/Desktop/testScripts/classObject_returnsList.py", line 32, in __setitem__
self._location = Point(self._location.x, value)
TypeError: __new__() takes exactly 4 arguments (3 given)
答案 0 :(得分:1)
您的Point
命名元组需要x
,y
和z
个参数:
Point = _collections.namedtuple("Point", ("x", "y", "z"))
虽然你只提供了其中两个;你可能也希望传递self._location.z
:
def __setitem__(self, key, value):
if key == 0:
self._location = Point(self._location.x, value, self._location.y)
else:
self._location = Point(value, self._location.y, self._location.z)
您还可以使用namedtuple._replace()
method替换特定属性(返回新实例):
def __setitem__(self, key, value):
if key == 0:
self._location = self._location._replace(y=value)
else:
self._location = self._location._replace(x=value)
如果您想使用索引来引用x
,y
和z
,请创建一个词典以作为关键字参数应用于namedtuple._replace()
:
def __setitem__(self, key, value):
coordinate = self._location._fields[key] # can raise IndexError, we want to propagate that
self._location = self._location._replace(**{coordinate: value})
我假设您的意思是0
为x
,而不是1
。
答案 1 :(得分:0)
只需更新以下方法,就可以正常工作了。感谢@Martijin睁开眼睛。
def __setitem__(self, key, value):
if key == 0:
self._location = Point(value, self._location.y, self._location.z)
elif key == 1:
self._location = Point(self._location.x, value, self._location.z)
elif key == 2:
self._location = Point(self._location.x, self._location.y, value)
else:
raise IndexError("%s takes %s has arguments. You are trying to update %s argument." % (
self.__class__.__name__,
len(self._location), key+1)
)
第二次更新:
def __setitem__(self, key, value):
""" update the value of argument like a dictionary
"""
try:
self._location = self._location._replace(**{'xyz'[key]: value})
except IndexError:
raise IndexError("%s takes %s has arguments. You are trying to update %s argument." % (
self.__class__.__name__,
len(self._location), key)
)