[英]Create a new class definition with different default arguments, using some other class definition?
说我在Python 2.7中有以下类:
class X():
def __init__(self, alpha=1):
self.alpha = alpha
print self.alpha
def beta(self, gamma=1):
self.gamma = gamma
self.omega = self.alpha + self.gamma
print self.omega
我想使用类定义来创建另一个具有不同默认参数的类定义,例如:
Y = f(X, alpha=2, gamma=2)
要么
Y = f(X, __init__.alpha=2, beta.gamma=2)
应该等于:
class Y():
def __init__(self, alpha=2):
self.alpha = alpha
print self.alpha
def beta(self, gamma=2):
self.gamma = gamma
self.omega = self.alpha + self.gamma
print self.omega
是否可以在Python 2.7(或3)中做类似的事情?
(我知道您可以使用functools.partial
对功能进行等效操作;因此,我想知道类是否存在类似的功能)
您可以编写一个为您创建类的函数:
def makeclass(alpha, gamma):
class C():
def __init__(self, alpha=alpha):
self.alpha = alpha
print self.alpha
def beta(self, gamma=gamma):
self.gamma = gamma
self.omega = self.alpha + self.gamma
print self.omega
return C
>>> X = makeclass(1, 1)
>>> Y = makeclass(2, 2)
>>> x = X() # X is the class, x is an instance
1
>>> x.beta()
2
>>> y = Y()
2
>>> y.beta()
4
可以做到,但是有点混乱。
这段代码:
class Foo(base1, base2, ...):
bar = something
baz = something_else
def qux(self):
...
...相当于此代码,但是如果Foo
是经典类,我不确定这是否正确:
Foo = type('Foo', (base1, base2, ...), {'bar': something, 'baz': something_else,
'qux': lambda self: ...})
因此,我们可以即时创建类,并将自定义方法对象附加到它们。
对于您的特定情况,我们需要进行这些调用(假设您通过从object
继承将X转换为新样式的类)。 首先,我们从X提取方法并应用functools.partial
:
new_init = functools.partial(X.__init__.im_func, # Just X.__init__ in 3.x
alpha=2)
new_beta = functools.partial(X.beta.im_func, # Just X.beta in 3.x
gamma=2)
im_func
属性im_func
绑定的方法对象中获取底层函数。 在Python 3中,没有诸如未绑定方法之类的东西,因此我们不需要使用此属性。 X.__init__
只是函数本身。
接下来,我们创建类:
Y = type('Y', (object,), {'__init__': new_init, 'beta': new_beta})
不幸的是,我们没有任何合理的方法来获取我们需要在此处重新定义的功能列表。 如果使用dir()
我们将获得许多不相关的特殊属性。 我们可以使用该类的__dict__
,但这将不包括任何继承的方法。 我认为我们可能需要搜索X.__mro__
以获取方法的完全正确列表:
result = {}
for class_ in X.__mro__:
for name, value in class_.__dict__.items():
if name not in result:
result[name] = value
我们还需要弄清楚每种情况下要覆盖哪些参数。 inspect.getargspec()
是一个很好的起点,但是,如果任何方法都是可变参数的(例如,它们采用*args
或**kwargs
参数),它都无济于事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.