2

このように、実行時にオブジェクトにメソッドを追加したいと考えています。

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 はメソッドをオブジェクトにバインドしていないようです。これを行うことは可能ですか?

4

3 に答える 3

5

タイプモジュールMethodTypeから使用できます:

import types

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

しかし、これは本当に必要ですか?デコレーターを探してください (たとえば)。必要な機能をクラスに追加するよりエレガントな方法です。

于 2015-11-27T05:50:05.490 に答える
1

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属性を使用してインスタンス オブジェクトを作成する別の関数が必要です。オブジェクトのdictは、 を介してアクセスできる属性の内部辞書のようなものです。コマンドを実行すると、JavaScript オブジェクトに似た Python オブジェクトが作成されます。

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.'

この関数は基本的に、インスタンス オブジェクトの一連の属性を作成するために、個別のリストをまとめて圧縮します。

于 2015-11-27T05:42:16.743 に答える
1

実際、seattrアタッチされているメソッドに self/object を渡すつもりはありません。
だからあなたができることは次のようなものです:

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()

于 2015-11-27T05:51:50.950 に答える