巨蟒复制建构子?

巨蟒是否有复制建构子? 如果没有,我会做什么来达到类似的效果?

现在的情况是,我正在使用一个库,并且我已经用额外的功能扩展了其中的一个类,我希望能够将我从库中获得的对象转换成我自己类的实例。

87725 次浏览

我觉得你想要 copy module

import copy


x = copy.copy(y)        # make a shallow copy of y
x = copy.deepcopy(y)    # make a deep copy of y

you can control copying in much the same way as you control pickle.

对于您的情况,我建议编写一个类方法(或者它可以是一个静态方法或者一个单独的函数) ,该方法以库的类的一个实例作为参数,并返回您的类的一个实例,其中复制了所有适用的属性。

在 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

A simple example of my usual implementation of a copy constructor:

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类继承了一个 pandas.DataFrame,并添加了大量其他需要重新计算的属性和方法,除非可以复制 other矩阵数据。我是如何找到这个问题的答案的。

我有一个类似的情况,不同之处在于新类只需要复制属性。因此,使用@Dunham 的想法,并为@meisterluk 的建议增加一些特殊性,@meisterluk 的“ copy _ structor”方法可以是:

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

下面的解决方案可能以简单的形式重复前面的一些解决方案。我不知道它是如何“勾兑”的权利,但它的工作原理和相当方便,在某些情况下,我使用它。

class Entity:
def __init__(self, code=None, name=None, attrs=None):
self.code = code
self.name = name
self.attrs = {} if attrs is None else attrs




def copy(self, attrs=None):
new_attrs = {k: v.copy() for k, v in self.attrs.items()} if attrs is None else attrs
return Entity(code=self.code, name=self.name, attrs=new_attrs)

用法:

new_entity = entity.copy()

这是一个更复杂的版本,允许干扰复制过程。我只在一个地方用过。还要注意,包含在 self.attrs中的对象也有这种“复制构造函数”。

This solution is not generic but is very simple and provides quite much control.

你可以实现这样的代码 不使用任何复制模块 Python 不支持方法重载 所以我们没有复制建构子

class student():
name: str
age: int


def __init__(self, other=None):
if other != None and isinstance(other, student):
self.name = other.name
self.age = other.age
elif not(isinstance(other,student)) and other!=None:
raise TypeError
def printInfo(s):
print(s.name, s.age)