簡體   English   中英

如何在運行時將方法綁定到python中的對象?

[英]How do you bind methods to objects in python during runtime?

我想這樣在運行時向對象添加方法。

class C(object):
  def __init__(self, value)
    self.value = value

obj = C('test')

def f(self):
  print self.value

setattr(obj, 'f', f)
obj.f()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes exactly 1 argument (0 given)

但是似乎setattr不會將方法綁定到對象。 是否有可能做到這一點?

您可以從類型模塊中使用MethodType

import types

obj.f = types.MethodType(f, obj)    
obj.f()

但是您真的需要這個嗎? 尋找裝飾器(例如),這是向類添加所需功能的更優雅的方法。

我發現有一種方法是使用locals()綁定空間和exec()命令。 首先,您必須從內置的exec()創建一個函數對象並將其解壓縮:

def make_function(name, parameter, commands):
    func = 'def {name}({parameter}):'.format(name=name,     parameter=parameter)
    for line in commands:
        func += '\n\t' + line
    exec(func)
    return locals()[name]

>>> func = make_function('help', 'pay', ['pay+=2', 'pay*=5', 'credit = pay//3', 'return credit'])
>>> func(8)
16

然后,您需要另一個函數,該函數使用dict屬性創建實例對象。 對象的字典就像它是可以通過被訪問的屬性內部字典。 命令,它使python對象類似於javascript對象。

def create_object(names, values):
    assert len(names) == len(values)
    exec('class one: pass')
    obj = locals()['one']()
    for i in range(len(names)):
       obj.__dict__[names[i]] = values[i]
    return obj

>>> func = make_function('help', 'pay', ['pay+=2', 'pay*=5', 'credit = pay//3', 'return credit'])
>>> test_obj = create_object(['help', 'interest', 'message'], [func, 0.5, 'please pay by thursday.'])
>>> test_obj.help(7)
15
>>> test_obj.interest
0.5
>>> test_obj.message
'please pay by thursday.'

此函數本質上將多個列表壓縮在一起,從而為您的實例對象創建了一組屬性。

實際上, seattr不會將自身/對象傳遞給所附加的方法。
所以您可以做的是這樣的:

class C(object):
    def __init__(self, value):
        self.value = value

obj = C('some thing')


def make_method(_object, *args, **kwargs):
    def f(self=_object):
        print self.value
    return f

setattr(obj, 'f', make_method(obj))
obj.f()

之所以起作用,是因為f()可以訪問make_method()范圍,因為它是一個內部/嵌套/關閉函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM