- Python Unlocked
- Arun Tigeraniya
- 570字
- 2021-07-23 14:57:48
Making calls to objects
Key 4: All objects can be made callable.
To reuse and group code for some task, we group it in the functions classes, and then call it with different inputs. The objects that have a __call__
attribute are callable and __call__
is the entry point. For the C class, tp_call
is checked in its structure:
>>> def func(): # a function ... print("adf") ... >>> func() adf >>> func.__call__() #implicit call method adf >>> func.__class__.__call__(func) adf >>> func.__call__ <method-wrapper '__call__' of function object at 0x7ff7d9f24ea0> >>> class C: #a callable class ... def __call__(self): ... print("adf") ... >>> c = C() >>> c() adf >>> c.__call__() #implicit passing of self adf >>> c.__class__.__call__(c) #explicit passing of self adf >>> callable(lambda x:x+1) #testing whether object is callable or not True >>> isinstance(lambda x:x+1, collections.Callable) #testing whether object is callable or not True
Methods in classes are similar to functions, except that they are called with an implicit instance as a first argument. The functions are exposed as methods when they are accessed from the instance. The function is wrapped in a method class and returned. The method class stores instances in __self__
and function in __func__
, and its __call__
method calls __func__
with first argument as __self__
:
>>> class D: ... pass ... >>> class C: ... def do(self,): ... print("do run",self) ... >>> def doo(obj): ... print("doo run",obj) ... >>> c = C() >>> d = D() >>> doo(c) doo run <__main__.C object at 0x7fcf543625c0> >>> doo(d) doo run <__main__.D object at 0x7fcf54362400> >>> # we do not need to pass object in case of C class do method ... >>> c.do() #implicit pass of c object to do method do run <__main__.C object at 0x7fcf543625c0> >>> C.doo = doo >>> c.doo() doo run <__main__.C object at 0x7fcf543625c0> >>> C.doo() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: doo() missing 1 required positional argument: 'obj' >>> C.do() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: do() missing 1 required positional argument: 'self' >>> C.do(c) do run <__main__.C object at 0x7fcf543625c0> >>> C.do(d) do run <__main__.D object at 0x7fcf54362400> >>> c.do.__func__(d) #we called real function this way do run <__main__.D object at 0x7fcf54362400>
Using this logic, we can also collect methods that are needed from other classes in the current class, like the following code, instead of multiple inheritances if data attributes do not clash. This will result in two dictionary lookups for an attribute search: one for instance, and one for class.
>>> #in library ... class PrintVals: ... def __init__(self, endl): ... self.endl = endl ... ... def print_D8(self, data): ... print("{0} {1} {2}".format(data[0],data[1],self.endl)) ... >>> class PrintKVals: #from in2 library ... def __init__(self, knm): ... self.knm = knm ... ... def print_D8(self, data): ... print("{2}:{0} {1}".format(data[0],data[1],self.knm)) ... >>> class CollectPrint: ... ... def __init__(self, endl): ... self.endl = endl ... self.knm = "[k]" ... ... print_D8 = PrintVals.print_D8 ... print_D8K = PrintKVals.print_D8 ... >>> c = CollectPrint("}") >>> c.print_D8([1,2]) 1 2 } >>> c.print_D8K([1,2]) [k]:1 2
When we call classes, we are calling its type, that is metaclass
, with class as a first argument to give us a new instance:
>>> class Meta(type): ... def __call__(*args): ... print("meta call",args) ... >>> class C(metaclass=Meta): ... pass ... >>> >>> c = C() meta call (<class '__main__.C'>,) >>> c = C.__class__.__call__(C) meta call (<class '__main__.C'>,)
Similarly, when we call instances, we are calling their type, that is class, with instance as first argument:
>>> class C: ... def __call__(*args): ... print("C call",args) ... >>> c = C() >>> c() C call (<__main__.C object at 0x7f5d70c2bb38>,) >>> c.__class__.__call__(c) C call (<__main__.C object at 0x7f5d70c2bb38>,)
- TypeScript Blueprints
- Python王者歸來
- Building a Recommendation Engine with Scala
- Access 2016數據庫管
- MySQL數據庫基礎實例教程(微課版)
- Python機器學習基礎教程
- Web Development with MongoDB and Node(Third Edition)
- 零基礎入門學習Python(第2版)
- Procedural Content Generation for C++ Game Development
- C/C++數據結構與算法速學速用大辭典
- 軟件項目管理實用教程
- Kivy Cookbook
- Getting Started with Electronic Projects
- Python 3快速入門與實戰
- Java多線程并發體系實戰(微課視頻版)