类中带有函数字典的self参数
我正在尝试在一个类里面创建一个可以执行的函数字典。但在处理self参数时遇到了麻烦。
看看下面的代码:
class myclass(object):
def x(self):
return 'x'
def y(self):
return 'y'
EF= {
'a':x,
'b':y,
}
def test(self):
print self.EF['a']()
当我尝试执行这个类的'test'函数时,出现了一个关于参数数量的错误,因为它在评估和执行字典中的某个函数。
>>> class myclass(object):
... def x(self):
... return 'x'
... def y(self):
... return 'y'
... EF= {
... 'a':x,
... 'b':y,
... }
... def test(self):
... print self.EF['a']()
...
>>>
>>>
>>> m=myclass()
>>> m.test()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in test
TypeError: x() takes exactly 1 argument (0 given)
我尝试了几种不同的方法,包括这个,但都不行。
EF= {
'a':self.x,
'b':self.y,
}
唯一有效的方法是我明确地把self作为参数传递,像这样。
... def test(self):
... print self.EF['a'](self)
...
>>> m=myclass()
>>> m.test()
x
我见过其他关于使用字典来索引函数的问题,但没有看到在类里面的。
我有以下几个问题:
- 处理self参数的正确方法是什么?
- 我希望把我的字典常量移到类外面的常量部分。可以这样做吗?如果可以,怎么做?这样做合适吗?
- 如果我必须把字典放在类里面,为什么不能把它移到类的顶部呢?
就这些了。谢谢你的帮助。
3 个回答
1
关于你的问题,类就像一个字典或者带名字的元组,里面包含了一些属性和可以执行的函数。这些函数本身只是定义了一些行为。self
就是和你的实例相关的一堆状态。如果你把这个函数的指针保存到别的地方,并且给它提供一个作为你类实例的self
,它应该就能正常工作。
class MyClass(object):
def __init__(self, x):
self.x = x
def fun(self):
return self.x
i = MyClass(1)
print i.fun()
f = MyClass.fun
i2 = MyClass(2)
print f(i2)
当你用标准的 i.fun()
调用时,它实际上只是把 i
隐式地作为 self
参数传递进去。
2
在初始化方法里放一个字典,这样就能正常工作了。
class Myclass(object):
def x(self):
return 'x'
def y(self):
return 'y'
def __init__(self):
self.EF= {
'a':self.x,
'b':self.y
}
def test(self):
print self.EF['a']()
m=Myclass()
m.test()
3
如何正确处理self参数?
在Python中,self
这个词的用法和其他一些编程语言中使用的this
很相似,但Python是明确的(明确总比模糊好!)
这让你可以把类当作一个实例化的对象来使用,或者直接使用这个类本身。
对于实例化的版本,你可能想要使用
>>> class myclass:
def __init__(self):
self.EF = {'a':self.x,'b':self.y}
def x(self):
return 'x'
def y(self):
return 'y'
def test(self):
print self.EF['a']()
>>> my_test_class = myclass()
>>> my_test_class.test()
x
我想把我的字典常量移到类外面的常量部分。这样可以吗?如果可以的话,应该怎么做?我应该这么做吗?
如果你想在类定义外部作为静态方法使用字典,你需要使用@staticmethod
这个装饰器。
>>> class myclass(object):
@staticmethod
def x():
return 'x'
@staticmethod
def y():
return 'y'
>>> EF = {'a':myclass.x,'b':myclass.y}
>>> EF['a']()
'x'
如果我必须把字典放在类里面,为什么不能把它放到类的顶部呢?
任何对象属性应该在__init__
函数中定义,或者通过明确的方式设置。