我有一个关于在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
- 参数?
答案 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)