我想创建一个类,其方法F依赖于类的对象被创建的“模式”。
下面的代码不工作,但希望它可以让你的什么,我试图做一个想法。 我的想法是在我定义设置每种模式(在这种情况下,函数或方法分配给self.f字典来,这样,而不是使用很多,如果elif的语句在init函数我刚刚分配正确的价值观使用字典。
class A(object):
_methods_dict={
'a':A.f1,
'b':A.f2
}
def __init__(self,mode = 'a'):
self.f = _methods_dict[mode]
def f1(self,x):
return x
def f2(self,x):
return x**2
我不明白为什么这不工作,你会怎么解决这个问题? 也有更好的(和更Python)接近得到同样的功能呢?
商店的两个函数的名称 ,然后使用getattr()
检索绑定的方法在__init__
:
class A(object):
_methods_dict = {
'a': 'f1',
'b': 'f2'
}
def __init__(self, mode='a'):
self.f = getattr(self, self._methods_dict[mode])
def f1(self, x):
return x
def f2(self, x):
return x ** 2
或者,只是代理的方法:
class A(object):
_methods_dict = {
'a': 'f1',
'b': 'f2'
}
def __init__(self,mode = 'a'):
self._mode = mode
@property
def f(self):
return getattr(self, self._methods_dict[self._mode])
def f1(self, x):
return x
def f2(self, x):
return x ** 2
该f
属性只是返回当前模式的正确绑定的方法。 使用属性简化调用签名处理,并为用户提供了实际的方法来反思,如果他们愿意的话。
任一方法具有相同的最终结果:
>>> a1 = A()
>>> a2 = A('b')
>>> a1.f(10)
10
>>> a2.f(10)
100
不同之处在于什么是存储在实例中,第一种方法商店绑定方法:
>>> vars(a1)
{'f': <bound method A.f1 of <__main__.A object at 0x10aa1ec50>>}
>>> vars(a2)
{'f': <bound method A.f2 of <__main__.A object at 0x10aa1ed50>>}
与在另一方的方法:
>>> vars(a1)
{'_mode': 'a'}
>>> vars(a2)
{'_mode': 'b'}
这似乎不是太大的差别,但后一种方法创建一个可腌制,没有问题的深复制实例。
你可以只让两个独立的类:
class Base(object):
# place here all attributes shared in common among the Modes
pass
class ModeA(Base):
def f(self, x):
return x
class ModeB(Base):
def f(self, x):
return x**2
def make_mode(mode, *args, **kwargs):
mode_dict = {'a':ModeA, 'b':ModeB}
return mode_dict[mode](*args, **kwargs)
a = make_mode('a')
print(a.f(10))
# 10
b = make_mode('b')
print(b.f(10))
# 100
要回答你的第一个问题(“为什么这不工作”):类对象“A”只被创建和绑定到模块的名称为“A”全班语句后(是的,“类”是一个可执行语句)块已经结束,所以你不能指既没有名称或该块内的类对象本身。