【发布时间】:2012-04-27 20:27:08
【问题描述】:
我想在运行时使用 __new__ 更改类的基类。 我拼命地看着,但我想不通。
class A(object): pass
class B(object): pass
class C(B):
some_attribute_in_c='hello'
def __new__(cls):
cls.__bases=(A,) #some code here to change the base class
return super(C,cls).__new__(A)
x=C()
x.some_attribute_in_c #return Error: x has no attribute 'some_attribute_in_c'
放入 __new__() 的正确代码是什么,以便最后一行返回 'hello' 并且 x 是具有基类 A 的 C 实例。
添加
我的用例如下。
class Pet(object):
some_attribute_in_pet='I\'m a pet.'
class Dog(Pet):
some_attribute_in_species='My species is dog.'
class Cat(Pet):
some_attribute_in_species='My species is cat.'
class PetBuyer(Pet):
def __new__(cls,desired_animal):
animal_bought=globals[desired_animal]
cls.__bases=(animal_bought,) #some code here to change the base class
return super(PetBuyer,cls).__new__(animal_bought)
def __init__(self,desired_animal):
print self.some_attribute_in_pet
print self.some_attribute_in_species
x = PetBuyer('Dog')
我想打印最后一行。
我是一只宠物。
我的物种是狗。
我的目标是在 PetBuyer 中使用 __new__() 就像动物类的工厂一样。 我这样做的原因是语法 PetBuyer('Dog') 在我的程序中很方便。
添加2
我这样做的原因如下。我必须编写的代码对我来说很复杂,因为我无法推断出正确的类设计。因此,无论如何我都可以对我的问题进行编码,因为我可以更好地理解它。但是,鉴于上述情况,我现在重构还为时过早。我还没有理解我的问题的某些组件之间的交互,在运行时更改基类将帮助我做到这一点。之后我会更适应重构。
【问题讨论】:
-
你没有。您在创建类时命名正确的基础。
-
a
PetBuyer几乎肯定不是Pet的一种,您通常可以通过在PetBuyer上添加Pet实例作为属性来组合这两种类型。 “奶奶有一只狗”而不是“奶奶是一只特殊的狗” -
@TokenMacGuy 请参阅 ADDED2 了解我这样做的动机。
-
__new__是一个类方法,所以你应该调用它的参数cls而不是self。 -
@ChrisMorgan 谢谢。我不清楚何时使用 cls 和 self.我更正了我的帖子。
标签: python