在python中复制构造函数?

Zit*_*rax 80 python constructor copy

python中有复制构造函数吗?如果不是我会做什么来实现类似的东西?

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

Tom*_*ham 62

我想你想要复制模块

import copy

x = copy.copy(y)        # make a shallow copy of y
x = copy.deepcopy(y)    # make a deep copy of y
Run Code Online (Sandbox Code Playgroud)

您可以控制复制的方式与控制泡菜的方式相同.

  • `deepcopy`适用于在类定义外部执行此操作.但@Zitrax希望在他的类定义中执行此操作,以便新实例从不同(父)类型(类)的对象继承属性(数据). (7认同)

qwe*_*967 23

在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
Run Code Online (Sandbox Code Playgroud)


God*_*ith 15

我通常实现复制构造函数的一个简单示例:

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)
Run Code Online (Sandbox Code Playgroud)

  • 好的。这会像 `Foo.from_foo(foo)` 一样工作。进一步的改进是使这项工作适用于 `Foo(foo)`,这可能是 OP @Zitrax 想要的。 (2认同)
  • 我不喜欢这个的原因是因为 1. 它强制 `__init__` 将 `data` 作为输入,并且对于更多类型不灵活 2. 它不允许重载 3. `__init__` 是公共的,你可以使用它如果您有其他构造函数类型,可能不需要。 (2认同)

Dav*_*d Z 11

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

  • 也许通过迭代`__dict__`? (2认同)

hob*_*obs 7

基于@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))
Run Code Online (Sandbox Code Playgroud)

此类ConfusionMatrix继承了 apandas.DataFrame并添加了大量其他需要重新计算的属性和方法,除非other可以复制矩阵数据。寻找解决方案是我发现这个问题的方式。

  • 请注意,此方法与许多其他语言的复制构造函数不同,因为它不会调用属性的复制构造函数。 (2认同)