Python中的方法参数

52

假设我有以下代码:

class Num:
    def __init__(self,num):
        self.n = num
    def getn(self):
        return self.n
    def getone():
        return 1
myObj = Num(3)

print(myObj.getn()) # result: 3

但是如果我尝试 print(myObj.getone()),我会得到一个错误:'getone()' takes no arguments (1 given)

所以我进行了替换:

def getone():
    return 1

使用

def getone(self):
    return 1

现在print(myObj.getone())显示为1,这是预期的。但是-getone()不需要任何参数只能返回1。我必须使用一个没有意义的参数吗?


8
它们不是毫无意义的。每个类的方法总是有一个隐式参数,即实例。在C++中也是一样的,但你永远不会在参数列表中看到它,因为它像魔法般从仙女森林的丛林里出现。Python则坚持“显示比隐式更好”。 - Stefano Borini
2
你可以使用@staticmethod和@classmethod装饰器来实现你想要的功能。请参考我回答中的示例。 - stderr
即使您将方法命名为__init(self,param)__,如果您没有缩进def,则可能会出现错误,因此__init__方法的范围不在类中... - Wolfgang Fahl
6个回答

65

在Python中:

  • 实例方法:需要使用self参数。
  • 类方法:以类作为第一个参数。
  • 静态方法:不需要实例(self)或类(cls)参数。

__init__是一个特殊的函数,如果没有覆盖__new__,它总是会将类的实例作为第一个参数。

以下是使用内置的classmethodstaticmethod装饰器的示例:

import sys

class Num:
    max = sys.maxint

    def __init__(self,num):
        self.n = num

    def getn(self):
        return self.n

    @staticmethod
    def getone():
        return 1

    @classmethod
    def getmax(cls):
        return cls.max

myObj = Num(3)
# with the appropriate decorator these should work fine
myObj.getone()
myObj.getmax()
myObj.getn()

话虽如此,我会尽量少用 @classmethod/@staticmethod。如果你发现自己正在创建只包含 staticmethod 的对象,则更符合Python风格的做法是创建一个新模块来存放相关的函数。


4
我认为你的回答里有些地方值得强调一下。我希望你不介意这些改进 :)!谢谢你的回答! - ivanleoncz

5

4

即使你的方法不使用self参数(它是附加到方法的实例的引用),也不能省略它。它必须始终存在,因为Python总会试图传递它。


2
在Python中,你必须始终向类方法传递至少一个参数,这个参数是self,它不是无意义的,而是指向实例本身的引用。

2

当前对象作为第一个参数显式传递给方法。 self 是常规名称。你可以随意更改名称,但强烈建议你遵循这个约定以避免混淆。


1
如果你执行 print(type(Num.getone)),你会得到 <class 'function'>
这只是一个普通的函数,可以像平常一样调用(不带参数):
Num.getone() # returns 1  as expected

但是如果你打印 print(type(myObj.getone)),你会得到 <class 'method'>
因此,当你从类的实例中调用 getone() 时,Python会自动将在类中定义的函数“转换”为方法。
实例方法要求第一个参数是实例对象。你可以把 myObj.getone() 看作是语法糖。
Num.getone(myObj) # this explains the Error 'getone()' takes no arguments (1 given).

例如:

例如:

class Num:
    def __init__(self,num):
        self.n = num
    def getid(self):
        return id(self)

myObj=Num(3)

现在,如果您
print(id(myObj) == myObj.getid())    
# returns True

如您所见,selfmyObj 是同一个对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接