Wenn Sie Python-Programmierung mit Dekoratoren studieren, werden Sie es bald vergessen, auch wenn Sie es sofort verstehen können. Also habe ich dieses Mal versucht, die Beispielanwendung zu betreiben, die dynamisch eine Methode hinzufügt, und notiert, welche Werte jeder Parameter enthält.
Dies ist ein Beispielprogramm, das die Methoden (func1, func2) mit Argumenten dekoriert.
sample1.py
import sys
import json
import logging
logging.basicConfig()
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
def api_method(api_name):
def _api_method(fn):
log.debug("fn={}".format(fn))
log.debug("api_name={}".format(api_name))
setattr(fn, '__api_name__', api_name)
return fn
return _api_method
class Sample(object):
def __init__(self):
log.debug(json.dumps(dir(self), sort_keys=False, indent=4))
self._api_methods = {}
for method_name in dir(self):
method = getattr(self, method_name)
try:
name = getattr(method, '__api_name__')
msg = 'API method {0} registered'.format(name)
log.debug(msg)
self._api_methods[name] = method
except AttributeError:
pass
log.debug("_api_methods=[%s]"%self._api_methods)
@api_method('func1')
def _func1(self, params):
print ("*** func1 : params=[%s]"%params)
return "func1 is done!"
@api_method('func2')
def _func2(self, params):
print ("*** func2 : params=[%s]"%params)
return "func2 is done!"
if __name__ == '__main__':
args = sys.argv
if len(args) == 3:
method = args[1]
params = args[2]
m = Sample()
result = m._api_methods[method](params)
print ("*** result=[%s]"%result)
Verschieben wir zunächst die Methode func1
$ python sample1.py func1 aaa
DEBUG:__main__:fn=<function Sample._func1 at 0x10dde60d0>
DEBUG:__main__:api_name=func1
DEBUG:__main__:fn=<function Sample._func2 at 0x10dde6158>
DEBUG:__main__:api_name=func2
DEBUG:__main__:[
"__class__",
"__delattr__",
"__dict__",
"__dir__",
"__doc__",
"__eq__",
"__format__",
"__ge__",
"__getattribute__",
"__gt__",
"__hash__",
"__init__",
"__init_subclass__",
"__le__",
"__lt__",
"__module__",
"__ne__",
"__new__",
"__reduce__",
"__reduce_ex__",
"__repr__",
"__setattr__",
"__sizeof__",
"__str__",
"__subclasshook__",
"__weakref__",
"_func1",
"_func2"
]
DEBUG:__main__:API method func1 registered
DEBUG:__main__:API method func2 registered
DEBUG:__main__:_api_methods=[{'func1': <bound method Sample._func1 of <__main__.Sample object at 0x10ddde898>>, 'func2': <bound method Sample._func2 of <__main__.Sample object at 0x10ddde898>>}]
*** func1 : params=[aaa]
*** result=[func1 is done!]
Versuchen Sie als Nächstes, die func2-Methode auszuführen
$ python sample1.py func2 bbb
DEBUG:__main__:fn=<function Sample._func1 at 0x10f9790d0>
DEBUG:__main__:api_name=func1
DEBUG:__main__:fn=<function Sample._func2 at 0x10f979158>
DEBUG:__main__:api_name=func2
DEBUG:__main__:[
"__class__",
"__delattr__",
"__dict__",
"__dir__",
"__doc__",
"__eq__",
"__format__",
"__ge__",
"__getattribute__",
"__gt__",
"__hash__",
"__init__",
"__init_subclass__",
"__le__",
"__lt__",
"__module__",
"__ne__",
"__new__",
"__reduce__",
"__reduce_ex__",
"__repr__",
"__setattr__",
"__sizeof__",
"__str__",
"__subclasshook__",
"__weakref__",
"_func1",
"_func2"
]
DEBUG:__main__:API method func1 registered
DEBUG:__main__:API method func2 registered
DEBUG:__main__:_api_methods=[{'func1': <bound method Sample._func1 of <__main__.Sample object at 0x10f971908>>, 'func2': <bound method Sample._func2 of <__main__.Sample object at 0x10f971908>>}]
*** func2 : params=[bbb]
*** result=[func2 is done!]
Ich konnte es richtig starten.
Dies ist ein Beispielprogramm, das auf die gleiche Weise funktioniert, ohne Dekorationen zu verwenden.
sample2.py
import sys
import json
import logging
logging.basicConfig()
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
class Sample(object):
def __init__(self):
log.debug(json.dumps(dir(self), sort_keys=False, indent=4))
def func1(self, params):
print ("*** func1 : params=[%s]"%params)
return "func1 is done!"
def func2(self, params):
print ("*** func2 : params=[%s]"%params)
return "func2 is done!"
if __name__ == '__main__':
args = sys.argv
if len(args) == 3:
method = args[1]
params = args[2]
m = Sample()
meth = getattr(m, method, None)
if meth:
result = meth(params)
print ("*** result=[%s]"%result)
Verschieben wir zunächst die Methode func1
$ python sample2.py func1 aaa
DEBUG:__main__:[
"__class__",
"__delattr__",
"__dict__",
"__dir__",
"__doc__",
"__eq__",
"__format__",
"__ge__",
"__getattribute__",
"__gt__",
"__hash__",
"__init__",
"__init_subclass__",
"__le__",
"__lt__",
"__module__",
"__ne__",
"__new__",
"__reduce__",
"__reduce_ex__",
"__repr__",
"__setattr__",
"__sizeof__",
"__str__",
"__subclasshook__",
"__weakref__",
"func1",
"func2"
]
*** func1 : params=[aaa]
*** result=[func1 is done!]
Versuchen Sie als Nächstes, die func2-Methode auszuführen
$ python sample2.py func2 bbb
DEBUG:__main__:[
"__class__",
"__delattr__",
"__dict__",
"__dir__",
"__doc__",
"__eq__",
"__format__",
"__ge__",
"__getattribute__",
"__gt__",
"__hash__",
"__init__",
"__init_subclass__",
"__le__",
"__lt__",
"__module__",
"__ne__",
"__new__",
"__reduce__",
"__reduce_ex__",
"__repr__",
"__setattr__",
"__sizeof__",
"__str__",
"__subclasshook__",
"__weakref__",
"func1",
"func2"
]
*** func2 : params=[bbb]
*** result=[func2 is done!]
Dies konnte auch richtig starten.
Beim Erstellen einer App, die Methoden dynamisch hinzufügt, ist es meines Erachtens einfacher, Code zu schreiben, ohne einen Dekorateur zu erstellen. Wann ist es jedoch wünschenswert, einen Dekorateur zu verwenden? Ich denke, es dient nur dazu, die Methode zu dekorieren, beispielsweise um eine DEBUG-Anweisung hinzuzufügen, also habe ich sie weiter erweitert.
sample3.py
import sys
import json
import logging
logging.basicConfig()
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
def api_method(api_name):
def _api_method(fn):
log.debug("fn={}".format(fn))
log.debug("api_name={}".format(api_name))
def _wrap(*args, **kwargs):
log.debug("--Vorverarbeitung-- [{}]".format(api_name))
ret = fn(*args, **kwargs)
log.debug("--Nachbearbeitung-- [{}]".format(api_name))
return ret
return _wrap
return _api_method
class Sample(object):
def __init__(self):
log.debug(json.dumps(dir(self), sort_keys=False, indent=4))
@api_method('func1')
def func1(self, params):
print ("*** func1 : params=[%s]"%params)
return "func1 is done!"
@api_method('func2')
def func2(self, params):
print ("*** func2 : params=[%s]"%params)
return "func2 is done!"
if __name__ == '__main__':
args = sys.argv
if len(args) == 3:
method = args[1]
params = args[2]
m = Sample()
meth = getattr(m, method, None)
if meth:
result = meth(params)
print ("*** result=[%s]"%result)
Verschieben wir zunächst die Methode func1
$ python sample3.py func1 aaa
DEBUG:__main__:fn=<function Sample.func1 at 0x10aba10d0>
DEBUG:__main__:api_name=func1
DEBUG:__main__:fn=<function Sample.func2 at 0x10aba11e0>
DEBUG:__main__:api_name=func2
DEBUG:__main__:[
"__class__",
"__delattr__",
"__dict__",
"__dir__",
"__doc__",
"__eq__",
"__format__",
"__ge__",
"__getattribute__",
"__gt__",
"__hash__",
"__init__",
"__init_subclass__",
"__le__",
"__lt__",
"__module__",
"__ne__",
"__new__",
"__reduce__",
"__reduce_ex__",
"__repr__",
"__setattr__",
"__sizeof__",
"__str__",
"__subclasshook__",
"__weakref__",
"func1",
"func2"
]
DEBUG:__main__:--Vorverarbeitung-- [func1]
*** func1 : params=[aaa]
DEBUG:__main__:--Nachbearbeitung-- [func1]
*** result=[func1 is done!]
Versuchen Sie als Nächstes, die func2-Methode auszuführen
$ python sample3.py func2 bbb
DEBUG:__main__:fn=<function Sample.func1 at 0x106a1d0d0>
DEBUG:__main__:api_name=func1
DEBUG:__main__:fn=<function Sample.func2 at 0x106a1d1e0>
DEBUG:__main__:api_name=func2
DEBUG:__main__:[
"__class__",
"__delattr__",
"__dict__",
"__dir__",
"__doc__",
"__eq__",
"__format__",
"__ge__",
"__getattribute__",
"__gt__",
"__hash__",
"__init__",
"__init_subclass__",
"__le__",
"__lt__",
"__module__",
"__ne__",
"__new__",
"__reduce__",
"__reduce_ex__",
"__repr__",
"__setattr__",
"__sizeof__",
"__str__",
"__subclasshook__",
"__weakref__",
"func1",
"func2"
]
DEBUG:__main__:--Vorverarbeitung-- [func2]
*** func2 : params=[bbb]
DEBUG:__main__:--Nachbearbeitung-- [func2]
*** result=[func2 is done!]
Es funktioniert jetzt gut. das ist alles
Recommended Posts