我们可以创建没有自我的实例方法吗

时间:2019-07-24 11:59:14

标签: python

我正在尝试创建具有一个实例方法的类,是否有可能在没有self的情况下创建实例方法。

class A():
    def display():
        print("Hi")

a = A()
a.display()

我变得像这样:类型错误:display()不接受任何参数(给定1个)

3 个答案:

答案 0 :(得分:2)

对于实例方法,您需要添加一个代表实例本身的参数。它必须存在并且必须是方法的第一个参数-这是强制性的,您不能更改它。尽管@classmethod def connect(cls, connection, password): r = super(PostgresqlReverseEngineering, cls).connect(connection, password) if r: ver = cls.execute_query(connection, "select version()").fetchone()[0] grt.log_info("PostgreSQL RE", "Connected to %s, %s\n" % (connection.name, ver)) ver_parts = [int(n) for n in ver.split()[1].rstrip(",").split(".")] + 4*[0] version = grt.classes.GrtVersion() version.majorNumber, version.minorNumber, version.releaseNumber, version.buildNumber = ver_parts[:4] cls._connections[connection.__id__]["version"] = version if version.majorNumber < 8: raise RuntimeError("PostgreSQL version %s is not a supported migration source.\nAt least version 8 is required." % ver) return r @classmethod 是社区使用的标准,您也可以遵循它。

self

现在,您可能已经注意到,class A(): def display(self): print('Hi') 方法中的实例并没有做任何特别的事情。为了避免这种冗余,我们需要使用其他类型的方法。

不将实例作为参数的方法称为静态方法,并由功能定义上方的display装饰器表示:

@staticmethod

这两个代码片段都将正确运行,并在执行以下代码时产生相同的输出:

class A():

    @staticmethod
    def display():
        print('Hi')

但是第二个版本是首选-因为显式要比隐式好。

答案 1 :(得分:0)

使用@staticmethod可以工作...但是我不建议初学者使用它

通常,函数定义对象行为,因此您将需要使用self来获取对象本身!

答案 2 :(得分:0)

正如其他人指出的那样,实例方法必须至少具有一个参数,因为对象本身(隐式)作为第一个参数传递。但是为什么

def语句与其他语句一样,定义了 function 而不是方法。那么该方法从何而来?让我们一步一步来。

class A:
    def display(self):
        print("Hi")

如果直接看一下存储类属性的字典,就会发现display绑定到function的实例上。

>>> type(A.__dict__['display'])
<class 'function'>

如果尝试使用普通的点语法访问属性,则会得到相同的结果:

>>> type(A.display)
<class 'function'>

但是,如果我们尝试通过类的 instance 访问该函数,则会发生某些不同的事情……

>>> type(A().display)
<class 'method'>

该方法来自哪里?每当您访问属性时,处理此类访问的机制都会查看结果是否具有__get__方法。 function类型提供了这样一种方法,因此您无需返回函数本身,而得到调用该函数的__get__方法的结果。也就是说,A().displayA.display.__get__(A(), A)确实是相同。 __get__返回的是一个执行以下两项操作的对象:

  1. 保存对实例A()的引用
  2. 保存对函数A.display的引用。

当您尝试调用该对象时,它所做的是获取传递给它的所有参数,并将保存的引用与这些参数一起传递给A(),并传递给函数{{1 }}。也就是说,

A.display

这是一个 为什么a = A() a.display() == A.display.__get__(a, A)(a) 定义的参数比看似必要的多。


其他人也提到了静态方法。 display是做什么的? @staticmethod是另一种类型,其实例包含一个函数。但是,staticmethod的{​​{1}}定义除了返回基础函数外没有做任何其他事情,没有返回任何新的staticmethod对象。因此给定

__get__

我们可以看到methodclass A: @staticmethod def display(): print("Hi") 的实例,而不是函数:

display

无论是否通过类访问属性,static method方法都会返回函数本身

>>> >>> type(A.__dict__['display'])
<class 'staticmethod'>

或实例

__get__
相关问题