在python中复制构造函数?
python中有一个复制构造函数吗? 如果不是,我会做什么来实现类似的东西?
情况是,我正在使用一个库,我已经扩展了其中的一个类,额外的function,我想能够将我从库中得到的对象转换为我自己的类的实例。
我想你想要复制模块
import copy x = copy.copy(y) # make a shallow copy of y x = copy.deepcopy(y) # make a deep copy of y
您可以像控制泡菜一样控制复制。
在Python中,可以使用默认参数定义复制构造函数。 比方说,你想要正常的构造函数运行函数non_copy_constructor(self)
和复制构造函数应该运行copy_constructor(self, orig)
。 然后你可以做到以下几点:
class Foo: def __init__(self, orig=None): if orig is None: self.non_copy_constructor() else: self.copy_constructor(orig) def non_copy_constructor(self): # do the non-copy constructor stuff def copy_constructor(self, orig): # do the copy constructor a=Foo() # this will call the non-copy constructor b=Foo(a) # this will call the copy constructor
对于您的情况,我会build议编写一个类方法(或者它可以是一个静态方法或一个单独的函数),它将一个类的实例作为参数,并返回一个类的实例,并复制所有可用的属性。
一个简单的例子,我通常的复制构造函数的实现:
import copy class Foo: def __init__(self, data): self._data = data @classmethod def from_foo(cls, class_instance): data = copy.deepcopy(class_instance._data) # if deepcopy is necessary return cls(data)
基于@Godsmith的思路和解决@ Zitrax的需要(我认为)在构造函数中为所有属性做数据拷贝:
class ConfusionMatrix(pd.DataFrame): def __init__(self, df, *args, **kwargs): try: # Check if `df` looks like a `ConfusionMatrix` # Could check `isinstance(df, ConfusionMatrix)` # But might miss some "ConfusionMatrix-elligible" `DataFrame`s assert((df.columns == df.index).all()) assert(df.values.dtype == int) self.construct_copy(df, *args, **kwargs) return except (AssertionError, AttributeError, ValueError): pass # df is just data, so continue with normal constructor here ... def construct_copy(self, other, *args, **kwargs): # construct a parent DataFrame instance parent_type = super(ConfusionMatrix, self) parent_type.__init__(other) for k, v in other.__dict__.iteritems(): if hasattr(parent_type, k) and hasattr(self, k) and getattr(parent_type, k) == getattr(self, k): continue setattr(self, k, deepcopy(v))
这个ConfusionMatrix
类inheritance了一个pandas.DataFrame
并添加了大量需要重新计算的其他属性和方法,除非可以复制other
matrix数据。 寻找解决scheme是我如何find这个问题。
我有类似的情况,因为新类只需要复制属性。 因此,使用@Dunham的想法并给@ meisterluk的build议增加一些特殊性,@ meisterluk的“copy_constructor”方法可以是:
from copy import deepcopy class Foo(object): def __init__(self, myOne=1, other=None): self.two = 2 if other <> None: assert isinstance(other, Foo), "can only copy instances of Foo" self.__dict__ = deepcopy(other.__dict__) self.one = myOne def __repr__(self): out = '' for k,v in self.__dict__.items(): out += '{:>4s}: {}, {}\n'.format(k,v.__class__,v) return out def bar(self): pass foo1 = Foo() foo2 = Foo('one', foo1) print '\nfoo1\n',foo1 print '\nfoo2\n',foo2
输出:
foo1 two: <type 'int'>, 2 one: <type 'int'>, 1 foo2 two: <type 'int'>, 2 one: <type 'str'>, one