我想在类(copy
)中创建方法(比如Parent
),它将返回调用它的类或子类的对象。我想要type(x) == type(x.copy())
。
我尝试过的方法都不令人满意。
init_me
,但这会破坏继承的目的。 __new__
和__init__
,但很快就决定Python必须有更好的方法。示例代码
class Parent(object):
def __init__(self, p1=p1_default, p2=p2_default, p3=p3_default):
... # common stuff
self._special_suff()
def copy_works_if_subclass_does_extra(self):
return self.init_me()
def copy_only_does_superclass(self):
return Parent()
def copy_with_init(self):
return self.__init__()
def whoami(self):
print('I am just a parent')
class Dad(Parent):
def _special_stuff():
... # Dad special stuff
return
def whoami(self):
print('I am a dad')
def init_me(self):
return Dad()
class Mom(Parent):
def _special_stuff():
... # Mom special stuff
return
def whoami(self):
print('I am a mom')
答案 0 :(得分:2)
如果我理解正确,您尝试在基类中编写copy
方法,该方法在派生类的实例上调用时仍然有效。这可以使用,但只有当您的子类只需要与基类相同的参数集时,它才会很容易。如果他们的__init__
方法需要不同的参数,那么每个派生类都需要单独的copy
方法。
以下是它如何运作的简单示例。诀窍是调用type(self)
来获取正确的类,然后使用适当的构造函数参数调用该类以获取新实例:
class Base(object):
def __init__(self, arg1, arg2, arg3):
self.attr1 = arg1
self.attr2 = arg2
self.attr3 = arg3
def copy(self):
cls = type(self)
return cls(self.attr1, self.attr2, self.attr3)
class Derived(Base):
def __init__(self, arg1, arg2, arg3):
super().__init__(arg1, arg2, arg3)
self.some_other_attr = "foo"
在实践中,这往往不起作用,因为Derived
类通常需要额外的参数来设置其额外属性。在这种情况下可能有效的选项是使用the copy
module而不是编写自己的copy
方法。函数copy.copy
将能够在没有任何特殊支持的情况下复制许多Python实例。
答案 1 :(得分:0)
你过于复杂的事情很多。在子类上实现简单构造函数的最小示例:
import copy
class Parent():
def whoami(self):
print('Just a parent')
def __init__(self, name):
self.name = name
def copy(self):
# Maybe copy.deepcopy instead
return copy.copy(self)
class Dad(Parent):
def whoami(self):
print('I am a dad')
def __init__(self, name):
super().__init__(name)
self.gender = 'Male'
如果你不需要,你甚至不需要Python中的构造函数。或者你可以在超类上有一个而在孩子身上没有。
一些用法:
>>> dad = Dad("Clark Griswold")
>>> dad.name
'Clark Griswold'
>>> dad.whoami()
I am a dad
>>> isinstance(dad, Dad)
True
>>> isinstance(dad, Parent)
True
>>> type(dad.copy()) == type(dad)
True