1

名前のリストがあるとします。これらをインスタンス関数としてクラス インスタンスに動的に追加できるようにしたいと考えています。私は types.MethodType について知っていますが、そこからここにたどり着くのは少し初心者です。基本的に私がやりたいことは次のとおりです。

class foo( object ):
     def __init__(self):
         pass

f = foo()
names = ["a","b","c"]
for name in names:
    add name() to f  # not sure what to do here
    # what I wanted added to instance "f" is this for each name:
    def name(self, *args, **kwargs):
        print( "My name is %s" % inspect.stack()[0][3]   )       
        print( "__called, args=%r, **kwargs=%r" % (args, kwargs) )

f.a() # ==> calls f.a()
f.b(1,2,3) # calls f.b(1,2,3 )and so on
4

2 に答える 2

5

関数をネストされた関数として作成すると、より簡単になります。name次に、ネストされたスコープから取得された変数です。

import types
def buildMethod(name, instance):
    def namefunc(self, *args, **kwargs):
        print "My name is %s" % name
        print "__called, args=%r, **kwargs=%r" % (args, kwargs)
    namefunc.__name__ = name
    setattr(instance, name, types.MethodType(namefunc, instance, type(instance)))

f = foo()
names = ["a","b","c"]
for name in names:
    buildMethod(name, f)

これにより、次の結果が得られます。

>>> f.a
<bound method instance.a of <__main__.foo instance at 0x100d8e560>>
>>> f.a.__name__
'a'
>>> f.a()
My name is a
__called, args=(), **kwargs={}
>>> f.b()
My name is b
__called, args=(), **kwargs={}
>>> f.c()
My name is c
__called, args=(), **kwargs={}
于 2012-11-30T18:23:45.137 に答える
1

setattr一人で十分だというのは間違っていました。ただし、これは機能します。

import inspect
import types

class foo( object ):
     def __init__(self):
         pass

def namefunc(self, *args, **kwargs):
    print( "My name is %s" % inspect.stack()[0][3]   )       
    print( "__called, args=%r, **kwargs=%r" % (args, kwargs) )

f = foo()
names = ["a","b","c"]
for name in names:
    setattr(f, name, types.MethodType(namefunc, f))

f.a() # ==> calls f.a()
f.b(1,2,3) # calls f.b(1,2,3 )and so on
于 2012-11-30T18:17:29.690 に答える