是否可以将python函数转换为类?
作者:互联网
我是C语言背景的Python新手,这是我第一次看到一种只包含对象的语言.我刚刚了解到,类和函数也只是对象.那么,有没有办法将以下函数转换为类?
In [1]: def somefnc(a, b):
...: return a+b
...:
我首先尝试将__call__变量分配给None,以消除该函数的“可调用性质”.但是,正如您所看到的,__call__被成功替换为None,但这并没有导致函数在调用时停止添加数字,尽管somefnc .__ call __(1,3)在分配somefnc .__ call__到None之前一直在工作.
In [2]: somefnc.__dict__
Out[2]: {}
In [3]: somefnc.__call__
Out[3]: <method-wrapper '__call__' of function object at 0x7f282e8ff7b8>
In [4]: somefnc.__call__ = None
In [5]: x = somefnc(1, 2)
In [6]: print(x)
3
In [7]: somefnc.__call__
In [8]: print(somefnc.__call__(1, 2))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
ipython-input-8-407663da97ca
in <module>()
----> 1 print(somefnc.__call__(1, 2))
TypeError: 'NoneType' object is not callable
In [9]: print (somefnc(1,2))
3
In [10]:
我不是出于开发目的而这样做,因此声称这是一种不良做法不会有任何意义.我只是想很好地理解Python.当然,出于开发目的,我宁愿创建一个类,也不愿将一个函数转换为一个类!
在取消了该函数添加两个数字的功能之后,我正在考虑通过修改somefun .__ dict__将有效函数分配给somefnc .__ init__属性和一些成员,以将其转换为类.
解决方法:
在Python中,函数是函数类的实例.因此,我将为您提供有关任何类和实例的一般答案.
In [10]: class Test:
...: def __getitem__(self, i):
...: return i
...:
In [11]: t = Test()
In [12]: t[0]
Out[12]: 0
In [13]: t.__getitem__(0)
Out[13]: 0
In [14]: t.__getitem__ = None
In [15]: t[0]
Out[15]: 0
In [16]: t.__getitem__(0)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-16-c72f91d2bfbc> in <module>()
----> 1 t.__getitem__(0)
TypeError: 'NoneType' object is not callable
在Python中,所有特殊方法(在前缀和后缀中带有双下划线的方法)是通过运算符而不是从实例触发时从类访问的.
In [17]: class Test2:
...: def test(self, i):
...: return i
...:
In [18]: t = Test2()
In [19]: t.test(1)
Out[19]: 1
In [20]: t.test = None
In [20]: t.test(1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-22-261b43cb55fe> in <module>()
----> 1 t.test(1)
TypeError: 'NoneType' object is not callable
按名称访问时,首先通过实例访问所有方法.差异是由于不同的搜索机制.当您通过名称访问方法/属性时,您将调用__getattribute__,它将默认情况下首先在实例的名称空间中进行搜索.通过运算符触发方法时,不会调用__getattribute__.您可以在反汇编中看到它.
In [22] import dis
In [23]: def test():
...: return Test()[0]
...:
In [24]: dis.dis(test)
2 0 LOAD_GLOBAL 0 (Test)
3 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
6 LOAD_CONST 1 (0)
9 BINARY_SUBSCR
10 RETURN_VALUE
In [25]: def test2():
...: return Test().__getitem__(0)
...:
In [26]: dis.dis(test2)
2 0 LOAD_GLOBAL 0 (Test)
3 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
6 LOAD_ATTR 1 (__getitem__)
9 LOAD_CONST 1 (0)
12 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
15 RETURN_VALUE
如您所见,在第一种情况下没有LOAD_ATTR. []运算符被汇编为特殊的虚拟机指令BINARY_SUBSCR.
标签:dynamic-languages,python-3-x,python 来源: https://codeday.me/bug/20191112/2023780.html