在python对象中使用self-parameter

时间:2012-07-25 06:07:29

标签: python class

我有一个关于在python中定义函数和自我参数的问题。

有以下代码。

class Dictionaries(object):
    __CSVDescription = ["ID", "States", "FilterTime", "Reaction", "DTC", "ActiveDischarge"]

    def __makeDict(Lst):
        return dict(zip(Lst, range(len(Lst))))

    def getDict(self):
        return self.__makeDict(self.__CSVDescription)

    CSVDescription = __makeDict(__CSVDescription)

x = Dictionaries()
print x.CSVDescription
print x.getDict()

x.CSVDescription运行正常。但print x.getDict()会返回错误。

TypeError: __makeDict() takes exactly 1 argument (2 given)

我可以将self - 参数添加到__makeDict()方法,但之后print x.CSVDescription将不起作用。

如何正确使用self - 参数?

2 个答案:

答案 0 :(得分:6)

在python中,self参数隐式传递给实例方法,除非该方法用@staticmethod修饰。

在这种情况下,__makeDict不需要对对象本身的引用,因此可以将其设置为静态方法,以便省略self

@staticmethod
def __makeDict(Lst): # ...

def getDict(self):
    return self.__makeDict(self.__CSVDescription)

答案 1 :(得分:3)

使用@staticmethod的解决方案在这里不起作用,因为从类主体本身调用方法不会调用描述符协议(如果它们是描述符,这对于普通方法也是一个问题 - 但这不是直到编译了类定义之后的情况。这里有四个主要选项 - 但其中大多数可以被视为某种程度的代码混淆,并且真的需要评论来回答“为什么不使用staticmethod?”这一问题。

首先,正如@Marcus建议的那样,总是从类中调用方法,而不是从实例调用。也就是说,每次执行self.__makeDict时,请执行self.__class__.__makeDict。这看起来很奇怪,因为这是一件奇怪的事情 - 在Python中,你几乎不需要像Class.method一样调用方法,并且你唯一一次(在super之前编写的代码变得可用) ),使用self.__class__将是错误的。

以类似的方式,但反过来说,你可以使它成为staticmethod并在类体中手动调用描述符协议 - 执行:__makeDict.__get__(None, Dictionaries)(__lst)

或者,您可以通过使用可选参数获得幻想来检测自己被调用的上下文:

def __makeDict(self, Lst=None):
    if Lst is None:
       Lst = self
    ...

但是,到目前为止,最好的方法是实现你在Python而不是Java工作 - 把它放在课外。

def _makeDict(Lst):
    ...

class Dictionaries(object):
   def getDict(self):
      return _makeDict(self.__CSVDescription)

   CSVDescription = _makeDict(__CSVDescription)