You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于Python Vector2类的对象拆分逻辑及相关使用疑问

Vector2类相关疑问解答

先看定义的Vector2类代码:

class Vector2:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

        if hasattr(x, "__getitem__"):
            x, y = x # why can we do this?
            self._v = [float(x), float(y)]
        else:
            self._v = [float(x), float(y)]

    def __getitem__(self, index):
        return self._v[index]

    def __setitem__(self, index, value):
        self._v[index] = 1.0 * value
        
    def __str__(self):
        return "(%s, %s)"%(self.x, self.y)

疑问1:为什么if hasattr(x, "__getitem__"):分支里能执行x, y = x?

能进入这个分支的x一定是可迭代对象——Python中,只要对象实现了__getitem__(或__iter__)方法,就支持迭代拆包。这里要求x刚好包含2个元素,比如x是元组(10,20)、列表[5,6],甚至是另一个Vector2实例(因为Vector2自身实现了__getitem__),所以x, y = x本质是把x这个可迭代对象的两个元素分别赋值给左边的x和y变量,完成参数拆包。

疑问2:hasattr(x, "__getitem__")的作用是什么?

hasattr(x, "__getitem__")用来检查x对象是否拥有__getitem__方法。拥有这个方法意味着:

  • 对象支持索引访问(比如x[0]、x[1]);
  • 对象属于可迭代类型(可以被遍历或拆包)。
    这段代码里用它判断用户是否传入了“复合参数”作为第一个参数,比如用户可能这样实例化:Vector2((100,200))或Vector2(Vector2(1,2)),此时进入分支把复合参数拆成x和y两个值,再存入self._v。

补充纠正:关于pygame blit()中使用v1[0]

之前误以为v1 = Vector2(100, 200)无法在pygame的blit()方法中用v1[0]指定x轴位置,实际是完全可行的:v1[0]和v1.x等价。因为Vector2实现了__getitem__方法,v1[0]会调用该方法返回self._v[0],而self._v初始化时就是用x、y转换后的float列表,所以v1[0]对应x坐标,v1[1]对应y坐标,符合pygame对位置参数的要求。

内容的提问来源于stack exchange,提问作者Nemo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 15:17:39