【问题标题】:Any elegant way to add a method to an existing object in python?有什么优雅的方法可以将方法添加到 python 中的现有对象?
【发布时间】:2015-05-18 12:59:36
【问题描述】:

经过大量搜索,我发现有几种方法可以将绑定方法或未绑定的类方法添加到现有实例对象中

这些方法包括以下代码所采用的方法。

import types


class A(object):
    pass


def instance_func(self):
    print 'hi'

def class_func(self):
    print 'hi'

a = A()

# add bound methods to an instance using type.MethodType
a.instance_func = types.MethodType(instance_func, a)                # using attribute
a.__dict__['instance_func'] = types.MethodType(instance_func, a)    # using __dict__

# add bound methods to an class
A.instance_func = instance_func
A.__dict__['instance_func'] = instance_func

# add class methods to an class
A.class_func = classmethod(class_func)
A.__dict__['class_func'] = classmethod(class_func)

让我恼火的是,输入函数的名称,instance_funcclass_func 两次。

是否有任何简单的方法可以将现有函数添加到类或实例中而无需再次输入函数的名称?

例如, A.add_function_as_bound_method(f) 将是向实例或类添加现有函数的优雅方式,因为该函数已经具有 __name__ 属性。

【问题讨论】:

    标签: python


    【解决方案1】:

    通常,存储在对象字典中的函数在您使用点分访问查找它们时不会自动变成绑定方法。

    也就是说,您可以使用functools.partial 预绑定函数并将其存储在对象字典中,以便可以像方法一样访问它:

    >>> from functools import partial
    >>> class Dog:
            def __init__(self, name):
                self.name = name
    
    
    >>> d = Dog('Fido')
    >>> e = Dog('Buddy')
    >>> def bark(self):                 # normal function
            print('Woof! %s is barking' % self.name)
    
    >>> e.bark = partial(bark, e)       # pre-bound and stored in the instance
    >>> e.bark()                        # access like a normal method
    Woof! Buddy is barking
    

    这是一种向现有对象添加方法的优雅方式(无需更改其类,也不会影响其他现有对象)。

    评论的跟进:

    您可以使用辅助函数来添加预绑定函数,只需一步:

    >>> def add_method(obj, func):
            'Bind a function and store it in an object'
            setattr(obj, func.__name__, partial(func, obj))
    

    像这样使用它:

    >>> add_method(e, bark)
    >>> e.bark()
    Woof! Fido is barking
    

    希望这正是您所需要的 :-)

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 2013-10-14
    • 2012-04-09
    • 2014-07-30
    • 2015-09-25
    • 1970-01-01
    • 2012-05-08
    相关资源
    最近更新 更多