__点(x,y)类在Python中的setitem_uu实现
我试图用python创建一个Point类。我已经实现了一些函数,比如_uu _u _; str uu u uu u u _u _;或_u u u。 我面临的唯一问题是,我的_uuuuItem_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 这是我的Point类,最后一个函数是我的_uuu_uuu项目_uuu:__点(x,y)类在Python中的setitem_uu实现,python,python-2.7,Python,Python 2.7,我试图用python创建一个Point类。我已经实现了一些函数,比如_uu _u _; str uu u uu u u _u _;或_u u u。 我面临的唯一问题是,我的_uuuuItem_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 这是我的Point类,最后一个函数是我的_uuu_uuu项目_uuu: class point(object): def __init__(self,x=0,y=0)
class point(object):
def __init__(self,x=0,y=0):
self.x=x
self.y=y
def __str__(self):
return "point(%s,%s)"%(self.x,self.y)
def __getitem__(self,item):
return (self.x, self.y)[item]
def __setitem__(self,x,y):
[self.x, self.y][x]=y
它应该是这样工作的:
p=point(2,3)
p[0]=1 #sets the x coordinate to 1
p[1]=10 #sets the y coordinate to 10
x, y = [2], [3]
[x, y][0][0] = 1
print(x[0])
(我说得对吗,设置项是否应该像这样工作?)
谢谢 让
self.data
且仅self.data
保存坐标值。
如果self.x
和self.y
也存储了这些值,那么self.data
和self.x
或self.y
很可能不会得到一致的更新
相反,使x
和y
从self.data
中查找它们的值
class Point(object):
def __init__(self,x=0,y=0):
self.data=[x, y]
def __str__(self):
return "point(%s,%s)"%(self.x,self.y)
def __getitem__(self,item):
return self.data[item]
def __setitem__(self, idx, value):
self.data[idx] = value
@property
def x(self):
return self.data[0]
@property
def y(self):
return self.data[1]
声明
[self.x, self.y][x]=y
这很有趣,但有问题。让我们把它分开:
[self.x,self.y]
使Python构建一个新列表,其值为self.x
和self.y
somelist[x]=y
使Python将值y
赋给somelist
的x
th索引。因此,这个新列表somelist
将得到更新。但这对self.data
、self.x
或self.y
没有影响。这就是您的原始代码无法工作的原因。让我们将其降至最低限度:
x, y = 2, 3
[x, y][0] = 1
print(x)
这将打印出2
为什么?
嗯,[x,y]
是一个包含两个元素的全新列表。当您将其第一个成员重新分配给1
时,这只会更改全新的列表,因此它的第一个元素现在是1
,而不是2
。它不会将数字2
转换为数字1
由于您的代码本质上与此相同,因此也存在相同的问题。只要变量具有不可变的值,就不能对变量进行变异
您可以通过执行以下操作来修复它:
p=point(2,3)
p[0]=1 #sets the x coordinate to 1
p[1]=10 #sets the y coordinate to 10
x, y = [2], [3]
[x, y][0][0] = 1
print(x[0])
现在您将获得1
为什么??嗯,[x,y]
是一个包含两个元素的新列表,每个元素都是一个列表。你不是用别的东西替换它的第一个元素,而是用别的东西替换它的第一个元素的第一个元素。但是它的第一个元素是与x
相同的列表,因此您也将x
的第一个元素替换为其他元素
如果这在你的头脑中有点难以保持清醒……那么,这通常是一个迹象,表明你正在做一些你可能不应该做的事情。(另外,对于表示“选择
x
或y
”的参数,使用x
,而对于表示“新值”的参数,使用y
,这一事实让人更加困惑……)
做同样的事情有很多简单的方法:
- 使用
/if
语句,而不是试图装腔作势else
- 使用一个
而不是两个整数值:列表
。(这是联合国大学的答案。)self.values[x]=y
- 使用一个
而不是两个整数值:dict
self.values['xy'[x]]]=y
- 使用
setattr(self,'xy'[x],y)
- 使用名为tuple的
而不是自己尝试构建相同的东西
\uuuuu setitem\uuuuuuu
尝试以下操作:
def __setitem__(self,coord,val):
if coord == 0:
self.x = val
else:
self.y = val
这是对
\uuuuu setitem\uuuuu
的滥用,但是。。。如果可能的话,我建议找出一种不同的方法来设置x/y坐标。无论您如何实现,使用p.x和p.y都将比p[0]和p[1]快得多。这在Python2.6中有效,我想它也适用于2.7
\uuuu setitem\uuu方法接受3个参数(self、index、value)
在这种情况下,我们希望使用index as int从\uuuuuuuuuuuuuuuuuuuuuuuuuuuuu>元组中检索坐标的名称(检查\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>的文档对性能非常有用)
请记住,使用\uuuu插槽时,仅允许x和y属性!因此:
p = Point()
p.x = 2
print(p.x) # 2.0
p.z = 4 # AttributeError
print(p.z) # AttributeError
使用@propertydecorator(当您开始拥有10000多个实例时),这种方法会更快
这是我给你的建议:)
类点(对象):
__槽坐标=('x','y')#坐标
定义初始化(self,x=0,y=0):
'''
可以通过多种方式使用构造函数:
Point()-无效参数
点(0,1)-传递两个参数
点(x=0,y=1)-传递关键字参数
点(**{x':0,'y':1})-解包字典
点(*[0,1])-解包列表或元组(或泛型iterable)
点(*点(0,1))-复制构造函数(解包点本身)
'''
self.x=x
self.y=y
定义设置属性(自身、属性、值):
对象。设置属性(self,attr,float(value))
定义uu获取项目uu(自身,索引):
'''
p=点()
p[0]#与self.x相同
p[1]#与self.y相同
'''
返回self.\uuuuGetAttribute\uuuuuuuuuuuuuuuu(self.\uuuuuuuuuuuuuu插槽\uuuuuuuuuuuuu[index])
定义设置项(自身、索引、值):
'''
p=点()
p[0]=1
p[1]=-1
印刷品(报告(p))#
'''
self.uuu setattr.uuu(self.uuu slots.[index],value)#由uuu setattr自动转换为float__
定义(自我):
'''
p=点()
打印(len(p))#2
'''
返回2
定义(自我):
'''
允许您进行迭代
p=点()
对于p的合作:
打印(坐标)
对于范围内的i(len(p)):
打印(p[i])
'''
还它
from collections import namedtuple
Point= namedtuple('Point', ['x','y'])
fred = Point (1.0, -1.0)
#Result: Point(x=1.0, y=-1.0)
class point(object):
def __init__(self,x=0,y=0):
self.x=x
self.y=y
def __str__(self):
return "point(%s,%s)"%(self.x,self.y)
def __getitem__(self,item):
return self.__dict__[item]
def __setitem__(self,item,value):
self.__dict__[item] = value
In [26]: p=point(1,1)
In [27]: print p
point(1,1)
In [28]: p['x']=2
In [29]: print p
point(2,1)
In [30]: p['y']=5
In [31]: print p
point(2,5)
from collections import namedtuple
Deck = namedtuple('cards',['suits','values'])
class FrenchDeck(object):
deck = [str(i) for i in range(2,11)]+list('JQKA')
suits = "heart clubs spades diamond".split()
def __init__(self):
self.totaldecks = [Deck(each,every) for each in self.suits for every in self.deck]
def __len__(self):
return len(self.totaldecks)
def __getitem__(self,index):
return self.totaldecks[index]
def __setitem__(self,key,value):
self.totaldecks[key] = value
CardDeck = FrenchDeck()
CardDeck[0] = "asdd" # needs`__setitem__()`
print CardDeck[0]
TypeError: 'FrenchDeck' object does not support item assignment