我正在尝试创建具有一个实例方法的类,是否有可能在没有self的情况下创建实例方法。
class A():
def display():
print("Hi")
a = A()
a.display()
我变得像这样:类型错误:display()不接受任何参数(给定1个)
答案 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().display
与A.display.__get__(A(), A)
确实是相同。 __get__
返回的是一个执行以下两项操作的对象:
A()
的引用A.display
的引用。当您尝试调用该对象时,它所做的是获取传递给它的所有参数,并将保存的引用与这些参数一起传递给A()
,并传递给函数{{1 }}。也就是说,
A.display
这是一个 为什么a = A()
a.display() == A.display.__get__(a, A)(a)
定义的参数比看似必要的多。
其他人也提到了静态方法。 display
是做什么的? @staticmethod
是另一种类型,其实例包含一个函数。但是,staticmethod
的{{1}}定义除了返回基础函数外没有做任何其他事情,没有返回任何新的staticmethod
对象。因此给定
__get__
我们可以看到method
是class A:
@staticmethod
def display():
print("Hi")
的实例,而不是函数:
display
无论是否通过类访问属性,static method
方法都会返回函数本身
>>> >>> type(A.__dict__['display'])
<class 'staticmethod'>
或实例
__get__