首页 > 解决方案 > 没有任何装饰器或“自我”的类中的函数

问题描述

我有以下带有函数的类:

class A: 
    def myfn():
        print("In myfn method.")

在这里,该函数没有self作为参数。它也没有@classmethod@staticmethod作为装饰器。但是,如果使用类调用它,它可以工作:

A.myfn()

输出:

In myfn method.

但如果从任何实例调用,则会出现错误:

a = A()
a.myfn()

错误输出:

Traceback (most recent call last):
  File "testing.py", line 16, in <module>
    a.myfn()
TypeError: myfn() takes 0 positional arguments but 1 was given

可能是因为self也作为参数发送。

这会调用什么样的函数?它会是一个静态函数吗?在类中使用这样的函数是否可取?缺点是什么?

编辑:此函数仅在使用类而不是对象/实例调用时才有效。我的主要问题是这样的函数叫什么?

Edit2:从答案看来,这种类型的功能尽管是最简单的形式,但不被接受为合法的。但是,由于在许多答案中都没有提到严重的缺点,我发现这可能是一个有用的构造,尤其是在我可以根据需要调用的类中分组我自己的静态函数时。我不需要创建此类的任何实例。至少,它使我免于@staticmethod每次打字,并使代码看起来不那么复杂。它也可以巧妙地派生出来,以便有人扩展我的课程。尽管所有这些功能都可以保留在顶级/全局级别,但将它们保留在类中更加模块化。但是,我觉得应该为这样一个以这种特定方式工作的简单构造指定一个特定的名称,并且它应该被认为是合法的。它也可以帮助初学者理解为什么selfPython 类中的常用函数需要参数。这只会增加这种伟大语言的简单性。

标签: pythonfunctionoop

解决方案


function类型实现了描述符协议,这意味着当您myfn通过类或类的实例访问时,您不会得到实际的函数;相反,您会得到该函数__get__方法的结果。那是,

A.myfn == A.myfn.__get__(None, A)

这里,myfn是一个实例方法,尽管它没有被正确定义为这样使用。但是,当通过class访问时,返回值__get__只是函数对象本身,并且可以像调用静态方法一样调用该函数。

通过实例访问会导致对 的不同调用__get__。如果a是 的一个实例A,那么

a.myfn() == A.myfn.__get__(a, A)

这里 ,__get__本质上试图返回 to 的部分应用myfna但是因为myfn不接受任何参数,所以失败了。

你可能会问,什么静态方法?staticmethod是一种包装函数并定义自己的__get__方法的类型。无论属性是通过类还是实例访问,该方法都会返回底层函数。否则,静态方法和普通函数之间几乎没有区别。


推荐阅读