【问题标题】:Is it possible to add a method to a Python list instance?是否可以向 Python 列表实例添加方法?
【发布时间】:2016-01-09 19:55:02
【问题描述】:

我正在尝试“猴子补丁”列表的实例。请注意,这不是 my 列表。我无法控制它的创建。据我所知,这在 2.7 中是不可能的。我对吗? 3.x可以吗?

【问题讨论】:

    标签: python list monkeypatching


    【解决方案1】:

    不,您不能在 list 对象上添加或删除属性,在 Python 2 和 Python 3 中都不能。

    您最多可以将这样的对象包装在另一个实例中,该实例实现与列表相同的属性和方法,但将对这些对象的访问权传递给包装的列表对象。

    该包装器可以使用UserList.UserList() class 实现:

    try:
        # Python 2
        from UserList import UserList
    except ImportError:
        # Python 3
        from collections import UserList
    
    class ListWrapper(UserList):
        def extra_method(self):
            return """Hi! I'm an extra method on this "list" (wink, wink)"""
    

    演示:

    >>> some_list = ['foo', 'bar', 'baz']
    >>> wrapped_list = ListWrapper(some_list)
    >>> len(wrapped_list)
    3
    >>> wrapped_list[1]
    'bar'
    >>> wrapped_list.extra_method()
    'Hi! I\'m an extra method on this "list" (wink, wink)'
    

    【讨论】:

    • 每天学习新东西 :)
    • 在python 3中使用UserListlist有什么优势?
    • @Dunes:如果您将list子类化,任何返回新实例(例如连接)的方法或运算符都会再次返回常规list对象,而UserList子类将始终返回而是包装类。
    • @Dunes:啊,是的,__getitem__ 方法直接委托给self.data.__getitem__。这很容易解决,但考虑到 __add____mul__ 返回该类的一个实例,这仍然是出乎意料的。
    • @Dunes:在 Python 2 中,只要您不使用跨步(例如扩展切片符号),它就可以工作,因为使用了 __getslice__ 方法。但是 Python 3 完全删除了它(因为 __getitem__ 足以处理使用 slice() 对象的所有切片)。这确实是一个错误。
    【解决方案2】:

    这是一种轻量级的方法,可以将单个方法添加到list 的子类的单个实例中

    >>> import new
    >>> L = ['f', 'o', 'o']
    >>> M = type("list", (list, ), {})(L)
    >>> M.bar = new.instancemethod(lambda self: self * 2, M)
    >>> M.bar()
    ['f', 'o', 'o', 'f', 'o', 'o']
    

    【讨论】:

    • M + ['foo'] 返回一个常规的list 对象。
    猜你喜欢
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    相关资源
    最近更新 更多