为什么我不能使用join来实现__str__的对象列表?

Tar*_*tor 4 python duck-typing

我正在学习Python中的duck typing,我知道如果你为一个类实现一些特殊的方法,你可以愉快地使用内置的类方法

例如:

class A:
    def __init__(self,l):
        self._l = l
    def __iter__(self):
        return iter(self._l)
Run Code Online (Sandbox Code Playgroud)

如果我这样做,我可以使用for...in..,zip,以及其他一些内置的方法,也可以做一些其他的东西,比如实现 __setitem__(),所以我可以使用random.choice,random.shuffle,我觉得python很酷,但是我发现这个问题,我想使用join来打印我实现其__str__方法的一些对象,但它不起作用

我发现这是因为当我们使用join时,我们写它就好了';'.join(l),所以duck typing技巧对它不起作用,因为它使用str的方法而不是对象将被连接

但是为什么呢?因为很多人都建立了友好的鸭子打字方法,为什么不加入?

@SethMMorton是我的疑点,谢谢我知道我可以';'.join([str(i) for i in l])用来解决我的问题,但我不知道为什么python本身不做呢?

Sha*_*ger 6

回答"为什么":Python中的所有内容都可以转换为str,即使没有__str__,repr也可以在str请求表单时使用对象.Python可能很灵活,但你所描述的是弱类型(Python一般不做),而不是鸭子打字.存在__str__意味着你可以强制转换为字符串,但这并不意味着"是一个字符串".

允许使用for循环zip等迭代任意迭代不是弱类型,因为它是一个没有歧义的通用接口; iterables以相同的方式迭代,即使它们可能产生不同的类型.

实际的弱类型是危险的,因为它可以允许错误无声地传递.它在Python 3中尤为明显.如果str允许自动强制,你做了:

iterable_of_bytes_objects = b'123', b'456'

','.join(iterable_of_bytes_objects)
Run Code Online (Sandbox Code Playgroud)

你可以默默地产生"b'123',b'456'",当赔率,你只是忘记b了连接字符串上的前导,并且意味着:

b','.join(iterable_of_bytes_objects)
Run Code Online (Sandbox Code Playgroud)

或许你打算制作一个字符串,但忘记decodebytes.或许你想要repr每个对象str,或者等等.Python不知道,并且根据Python的Zen(import this):

面对模棱两可,拒绝猜测的诱惑.

以及:

显式优于隐式.

Coercing会自动隐藏错误,并涉及人们"可能想要"的猜测性猜测.如果你想强迫,那','.join(map(str, iterable))就是为了什么,但这意味着你选择了特定形式的强制,并且假设你知道你正在做什么,这与其他Zen要求相符:

错误不应该默默地传递.

除非明确沉默.