On 29/03/15 19:16, Paul Sokolovsky wrote: > Hello, > > I looked into porting Python3 codecs module to MicroPython and saw > rather strange behavior, which is best illustrated with following > testcase: > > ========== > def foo(a): > print("func:", a) > > import _codecs > fun = _codecs.utf_8_encode > #fun = hash > #fun = str.upper > #fun = foo > > > class Bar: > meth = fun > > print(fun) > print(fun("foo")) > b = Bar() > print(b.meth("bar")) > ========== > > Uncommenting either _codecs.utf_8_encode or hash (both builtin > functions) produces 2 similar output lines, which in particular means > that its possible to call a native function as (normal) object method, > which then behaves as if it was a staticmethod - self is not passed to > a native function. > > Using native object method in this manner produces error of self type > mismatch (TypeError: descriptor 'upper' for 'str' objects doesn't apply > to 'Bar' object). > > And using standard Python function expectedly produces error about > argument number mismatch, because used as a method, function gets extra > self argument. > > So the questions are: > > 1. How so, the native functions exhibit such magic behavior? Is it > documented somewhere - I never read or heard about that (cannot say I > read each and every word in Python reference docs, but read enough. As > an example, https://docs.python.org/3/library/stdtypes.html#functions > is rather short and mentions difference in implementation, not in > meta-behavior). In fact the "magic" is exhibited by Python functions, not by builtin ones. Python functions are descriptors, builtin functions are not. > > 2. The main question: how to easily and cleanly achieve the same > behavior for standard Python functions? I'd think it's staticmethod(), > but: > Write your own "BuiltinFunction" class which has the desired properties, ie. it would be callable, but not a descriptor. Then write a "builtin_function" decorator to produce such an object from a function. The class and decorator could be the same object. Personally, I think that such a class (plus a builtin function type that behaved like a Python function) would be a useful addition to the standard library. Modules do get converted from Python to C and vice-versa. >>>> staticmethod(lambda:1)() > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: 'staticmethod' object is not callable > > Surprise. > > (By "easily and cleanly" I mean without meta-programming tricks, like > instead of real arguments accept "*args, **kwargs" and then munge args). > > > Thanks, > Paul mailto:pmiscml at gmail.com Cheers, Mark
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4