動的/実行方法作成(コード生成)Python
-
22-08-2019 - |
質問
Iを生成しなければならないコードのための方法で行います。で走行できるように任意のコードとしてdocstring.
が浮かび上がったソリューションの組み合わせ exec
や setattr
, このダミーの例:
class Viking(object):
def __init__(self):
code = '''
def dynamo(self, arg):
""" dynamo's a dynamic method!
"""
self.weight += 1
return arg * self.weight
'''
self.weight = 50
d = {}
exec code.strip() in d
setattr(self.__class__, 'dynamo', d['dynamo'])
if __name__ == "__main__":
v = Viking()
print v.dynamo(10)
print v.dynamo(10)
print v.dynamo.__doc__
いい/安全/より慣用の方法をあげませんか?
解決
Theranのコードに基づいていますが、クラスのメソッドにそれを拡張ます:
class Dynamo(object):
pass
def add_dynamo(cls,i):
def innerdynamo(self):
print "in dynamo %d" % i
innerdynamo.__doc__ = "docstring for dynamo%d" % i
innerdynamo.__name__ = "dynamo%d" % i
setattr(cls,innerdynamo.__name__,innerdynamo)
for i in range(2):
add_dynamo(Dynamo, i)
d=Dynamo()
d.dynamo0()
d.dynamo1()
どの印刷する必要があります:
in dynamo 0
in dynamo 1
他のヒント
関数のドキュメンテーション文字列と名前が変更可能なプロパティです。あなたは、内部関数の中で、あなたが欲しいものを行う、あるいは()の間で選択makedynamo内部機能の複数のバージョンを持つことができます。文字列のうち、任意のコードをビルドする必要はありません。
ここではインタプリタのうち抜粋です。
>>> def makedynamo(i):
... def innerdynamo():
... print "in dynamo %d" % i
... innerdynamo.__doc__ = "docstring for dynamo%d" % i
... innerdynamo.__name__ = "dynamo%d" % i
... return innerdynamo
>>> dynamo10 = makedynamo(10)
>>> help(dynamo10)
Help on function dynamo10 in module __main__:
dynamo10()
docstring for dynamo10
Pythonできるのを宣言する機能機能んでいる exec
trickery.
def __init__(self):
def dynamo(self, arg):
""" dynamo's a dynamic method!
"""
self.weight += 1
return arg * self.weight
self.weight = 50
setattr(self.__class__, 'dynamo', dynamo)
いくつかのバージョンの機能をつけることができすべてのループを変化さんの名前の setattr
機能:
def __init__(self):
for i in range(0,10):
def dynamo(self, arg, i=i):
""" dynamo's a dynamic method!
"""
self.weight += i
return arg * self.weight
setattr(self.__class__, 'dynamo_'+i, dynamo)
self.weight = 50
(こんが、コードがいを得て).どの設定のdocstringをもたらすであろうと確信してがんにいかしています。
編集:設定できますのdocstringによ dynamo.__doc__
, でもなんとかこのようにループボディ:
dynamo.__doc__ = "Adds %s to the weight" % i
別編集:からの支援@elibenと@bobince、閉鎖問題を解決する必要がある.
class Dynamo(object):
def __init__(self):
pass
@staticmethod
def init(initData=None):
if initData is not None:
dynamo= Dynamo()
for name, value in initData.items():
code = '''
def %s(self, *args, **kwargs):
%s
''' % (name, value)
result = {}
exec code.strip() in result
setattr(dynamo.__class__, name, result[name])
return dynamo
return None
service = Dynamo.init({'fnc1':'pass'})
service.fnc1()
私の悪い英語のための私を許します。
私は最近、wxPythonの上の特定のフレームを開くには、各メニュー項目をバインドするために動的関数を生成する必要があります。ここで私は何をすべきかです。
まず、メニュー項目とフレームとの間のマッピングのリストを作成します。
menus = [(self.menuItemFile, FileFrame), (self.menuItemEdit, EditFrame)]
マッピングの最初の項目は、メニュー項目と最後の項目が開放されるフレームです。次に、私は、特定のフレームにメニュー項目のそれぞれからwx.EVT_MENUイベントを結合する。
for menu in menus:
f = genfunc(self, menu[1])
self.Bind(wx.EVT_MENU, f, menu[0])
genfunc関数は動的関数ビルダーであり、ここでコードは
def genfunc(parent, form):
def OnClick(event):
f = form(parent)
f.Maximize()
f.Show()
return OnClick