编程语言
首页 > 编程语言> > 是否可以将python函数转换为类?

是否可以将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