可以覆盖Python中的文字吗?

时间:2013-09-29 20:53:03

标签: python macropy

无法找到更好地标题的方法,请随意纠正。

我对Python很陌生,目前正在尝试使用该语言。我注意到所有内置类型都无法与其他成员一起扩展。我想举例说明each list类型的方法,但这是不可能的。我意识到它是出于效率原因而设计的,并且大多数内置类型都是用C实现的。

好吧,我发现重写此行为的原因之一就是定义了一个新类,它扩展了list但没有做任何事情。然后我可以将变量list分配给该新类,每次我想实例化一个新列表时,我都会使用list构造函数,就像它用于创建原始类一样list类型。

class MyList(list):
    def each(self, func):
       for item in self:
           func(item)
list = MyList

my_list = list((1,2,3,4))
my_list.each(lambda x: print(x))

输出:

1
2
3
4

当然,通过定义获取构建类型的方法并返回扩展该类型的类,可以概括这个想法。此外,原始list变量可以保存在另一个变量中以保持对它的访问。

我现在面临的唯一问题是,当你以文字形式(即list)实例化[1,2,3,4]时,它仍然会使用原始列表构造函数(或者它是什么? )。有没有办法覆盖这种行为?如果答案是否定的,您是否知道其他一些方法可以让用户扩展内置类型? (就像javascript允许扩展内置原型一样)。

我发现内置插件的这种限制(无法向其添加成员)是Python的一个缺点,使其与其他用户定义的类型不一致...总的来说我真的很喜欢这种语言,而我真的不喜欢理解为什么这个限制真的是必要的。

1 个答案:

答案 0 :(得分:19)

这是Python的一个尽责选择。

首先,关于修补内置类型,这主要是设计决策,其次只是优化。我从很多潜伏在Python邮件列表中的经验中了解到,对内置类型进行修补,虽然对于小脚本来说很有用,但对于任何更大的脚本都没有好处。

一方面,图书馆对类型做出了某些假设。如果鼓励扩展默认类型,许多库最终会互相争斗。它也会阻止制作新类型 - deque是deque,有序集是有序集,字典是字典,应该是。

字面语法是一个特别重要的观点。如果您不能保证[1, 2, 3]是一个列表,您能保证什么?如果人们可以改变这些行为,就会产生如此全球性的影响,从而破坏许多代码的稳定性。有一个原因 goto 并且不鼓励使用全局变量。


尽管如此,还有一个特别的黑客,我 喜欢。当你看到r"hello"时,这似乎是一个扩展的文字形式。

那么为什么不r[1, 2, 3]

class ListPrefixer:
    def __init__(self, typ):
        self.typ = typ

    def __getitem__(self, args):
        return self.typ(args)

class MyList(list):
    def each(self, func):
        return MyList(func(x) for x in self)

e = ListPrefixer(MyList)

e[1, 2, 3, 4].each(lambda x: x**2)
#>>> [1, 4, 9, 16]

最后,如果你真的想做深度AST黑客攻击,请查看MacroPy