覆盖builtins python类

时间:2014-03-12 11:14:54

标签: python class python-2.7 built-in

我正在寻找的是在python 2.7

中实现这一目标的方法
oldlist = list
class list(oldlist):
    def append(self, object):
        super(list, self).append(object)
        return self
    def sort(self, cmp=None, key=None, reverse=False):
        super(list, self).sort(cmp, key, reverse)
        return self
__builtins__.list=list
print list([3, 4, 1, 2]).append(5)
print list([3, 4, 1, 2]).append(5).sort()
print list([3, 4, 1, 2]).append(5).sort(reverse=True)
print list([3, 4, 1, 2]).append(5).sort()[0]
print [3, 4, 1, 2].append(5)
print [3, 4, 1, 2].append(5).sort()
print [3, 4, 1, 2].append(5).sort(reverse=True)
print [3, 4, 1, 2].append(5).sort()[0]

实际打印:

[3, 4, 1, 2, 5]
[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]
1
None
...
AttributeError: 'NoneType' object has no attribute 'sort'

应打印:

[3, 4, 1, 2, 5]
[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]
1
[3, 4, 1, 2, 5]
[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]
1

我知道编辑builtins类会很危险,但是有些方法确实没有返回任何内容,python脚本实际上是期望它们返回一些东西,那么问题是什么?

现在我觉得这很简单:

filterfiles(myfilelist.sort())

比做:

myfilelist.sort()    
filterfiles(myfilelist)

它允许在交互模式下(而不是没有)看到结果

2 个答案:

答案 0 :(得分:2)

  

我不明白的一点是,当我们放置{1:1, 2:2}时,python会将dict文字转换为dict对象,而且我知道我无法更改python来创建mydict的实例,但是有没有办法直接改变内置字典,而它使用一些hacky方式?

不,这根本不可能。文字,即任何文字(字符串,数字,列表,字母)都是Python语法的一部分。它们所代表的对象是在解析器中以非常低的级别创建的,早在您可以使用Python代码进行任何更改之前。

但还有另一件重要的事情。内置对象都是用本机代码实现的;它们实际上并不像Python环境中的Python对象那样存在。为此,__builtins__.dict之类的内容提供了本机字典类型的引用。使用文字创建对象时,会使用真正的本机类型,因此永远不会访问__builtins__.dict。因此,更改__builtins__.dict根本不会影响它。它只会改变环境,而这些引用实际上很重要。

你可以想象这样的情况:

# native code
class _InternalSpecialType:
    pass
def makeSpecialType (): # this is our “literal” evaluator
    return _InternalSpecialType()

# public interface
SpecialType = _InternalSpecialType

# then in the Python code
class NewSpecialType(SpecialType):
    pass
SpecialType = NewSpecialType

# using a “literal”
x = makeSpecialType()
print(type(x)) # _InternalSpecialType

所以不,你无法改变文字在幕后使用的内容。这根本不可能。如果您想拥有一个不同类型的对象,您将始终必须明确地创建它。然后最好将类型命名为与原始类型不同,以避免混淆(以及更改的类型和文字之间的不兼容性)。

最后,关于不允许链接的内置类型的方法:只是忍受它。 Guido明智地决定反对它,通常,Guido有很好的理由让你可以信任,所以它可能会更好(参见this answer)。

答案 1 :(得分:0)

我将解释如何解决您遇到的问题,而不是如何实施您之后的解决方案:

filterfiles(sorted(myfilelist))

返回None的方法是按设计进行的:在这种情况下,为了避免在您真正想要排序副本时无意中就地排序列表(并丢失其当前排序)。 Python已经为这种情况提供了功能性替代方案,例如在这种情况下sorted(),当它有意义时。请注意,sorted()不会修改其参数。

如果您确实找到了没有提供功能替代的用例,我建议您以相同的方式解决它:编写一个返回您想要查看的内容的函数(而不是方法)。 (但首先查看python的functools模块。)