python中关于拆包的疑问

来源:2-1 python中一切皆对象

慕粉3573892

2020-06-04

class Vector2d:
    typecode = 'd'

    def __init__(self, x, y):
        self.x = float(x)
        self.y = float(y)

    def __iter__(self):
        return (i for i in (self.x, self.y))

    def __repr__(self):
        class_name = type(self).__name__
        return '{}({!r}, {!r})'.format(class_name, *self)    #(1)

    def __str__(self):
        return str(tuple(self))

    def __bytes__(self):
        return (bytes([ord(self.typecode)]) +
                bytes(array(self.typecode, self)))

    def __eq__(self, other):
        return tuple(self) == tuple(other)

    def __abs__(self):
        return math.hypot(self.x, self.y)

    def __bool__(self):
        return bool(abs(self))

我在读《流畅的python》,上面代码(1)处的self,我不明白这里为什么要加号,这个类实现了__iter__,可以迭代,拆包,直接写self不就可以把self.x,self.y传后两个{!r}里了吗?在我的理解中,只有定义不定参数的函数形参中会用到*,还有就是平行赋值,比如:

>>> a, b, *rest = range(5)
>>> a, b, rest
(0, 1, [2, 3, 4])
写回答

1回答

bobby

2020-06-04

  1. 括号一般就是显示用的,没有什么意义

  2. !r :将对象格式化转换成repr

  3. *self 就是将这个拆包,因为字符串中有三个参数  直接写self不行,因为直接写self就是一个可迭代的对象,不是拆成两个参数而是一个参数 无非这个参数就是一个可迭代对象而已

  4. 在我的理解中,只有定义不定参数的函数形参中会用到*,还有就是平行赋值,这里理解不对 不需要和参数定义形式对比 你要的结果本来应该是 return '{}({!r}, {!r})'.format(class_name, self.x, self.y)  

  5. 上面的format很容易看懂 self.x, self.y 将这两个字符串使用一个*self拆包 无非就是少写一个参数而已 如果你的__iter__返回的是三个值比如 return self.x,self.y, self.x(这里只是假设,这样写实际上会报错) 那么'{}({!r}, {!r})'.format(class_name, *self)就等效于  '{}({!r}, {!r})'.format(class_name, self.x, self.y, self.x)这里一看就知道实际传递进去的数量多了 会报错的

0
0

Python3高级核心技术97讲,高级进阶的必学课程

socket编程/多线程/多进程/线程池/asyncio并发编程/协程和异步IO

2121 学习 · 551 问题

查看课程