简体   繁体   English

如何在python中使用Deepcopy创建实例?

[英]How to create an instance with deepcopy in python?

I'm trying to inherit Decimal and create a math class than can handle polymorphic input. 我正在尝试继承Decimal并创建一个数学类,该类不能处理多态输入。 The problem I'm running into is that nothing I do seems to allow me to create duplicate instances. 我遇到的问题是我似乎没有做任何事情允许我创建重复的实例。

I've looked at dozens of examples, but nothing I've found actually creates multiple instances from an internal constructor. 我看了几十个例子,但是我发现实际上没有从内部构造函数创建多个实例。 They all do it from outside. 他们都是从外面做的。

To have overridden math functions with polymorphic input, the instance-constructor MUST be internal to the class. 要使用多态输入覆盖数学函数,实例构造函数必须在类内部。 There is no other way. 没有别的办法了。 I've been over this ten different ways, looked at tons of online docs ( mostly flat out wrong ) Hopefully somebody here can help. 我经历过这十种不同的方式,查看了大量的在线文档(大多数情况下都是错误的),希望这里的人能对您有所帮助。

#
class:  Amount
baseclass:  <class 'decimal.Decimal'>
instance:  0x7f821c830ca8
postinitclass:  Amount
postinitbaseclass:  <class 'decimal.Decimal'>
postinitinstance:  0x7f821c830ca8
Amounts: 
    self:  0x7f821c830ca8
    copy:  0x7f821c830ca8
        setting from:  float
    self:  0x7f821c830ca8
    copy:  0x7f821c830ca8
        setting from:  float
    self:  0x7f821c830ca8
    copy:  0x7f821c830ca8
        setting from:  float
REPORT:  <class 'FOO.Amount'> Amount 0x7f821c830ca8 0
REPORT:  <class 'FOO.Amount'> Amount 0x7f821c830ca8 0
REPORT:  <class 'FOO.Amount'> Amount 0x7f821c830ca8 0
    self:  0x7f821c830ca8
    copy:  0x7f821c830ca8
        setting from:  Amount
    self:  0x7f821c830ca8
    copy:  0x7f821c830ca8
ADDING:
    defined values 0 : 0
Amount 0x7f821c830ca8 0
0 : 0
0 : 0 : 0
#
 ### testfoo.py import sys from decimal import Decimal,getcontext import socket import operator import re import FOO # set the class currency type Factory = FOO.Amount() print ("Amounts: ") m0 = Factory.newamount(0.1) m1 = Factory.newamount(0.02) m2 = Factory.newamount(0.03) print ("REPORT: ", m0.__class__, type(m0).__name__, hex(id(m0)), m0) print ("REPORT: ", m1.__class__, type(m1).__name__, hex(id(m0)), m1) print ("REPORT: ", m2.__class__, type(m2).__name__, hex(id(m0)), m2) m3 = m2 + m1 print (type(m3).__name__, hex(id(m3)), m3) print (m1,":", m2) print (m1,":",m2,":",m3) 
#
 class: Amount baseclass: <class 'decimal.Decimal'> instance: 0x7f821c830ca8 postinitclass: Amount postinitbaseclass: <class 'decimal.Decimal'> postinitinstance: 0x7f821c830ca8 Amounts: self: 0x7f821c830ca8 copy: 0x7f821c830ca8 setting from: float self: 0x7f821c830ca8 copy: 0x7f821c830ca8 setting from: float self: 0x7f821c830ca8 copy: 0x7f821c830ca8 setting from: float REPORT: <class 'FOO.Amount'> Amount 0x7f821c830ca8 0 REPORT: <class 'FOO.Amount'> Amount 0x7f821c830ca8 0 REPORT: <class 'FOO.Amount'> Amount 0x7f821c830ca8 0 self: 0x7f821c830ca8 copy: 0x7f821c830ca8 setting from: Amount self: 0x7f821c830ca8 copy: 0x7f821c830ca8 ADDING: defined values 0 : 0 Amount 0x7f821c830ca8 0 0 : 0 0 : 0 : 0 

I believe you are going about this the wrong way. 我相信您会以错误的方式进行操作。 You have effectively created a copy of the __init__ method in newamount . 您已经有效地在newamount创建了__init__方法的newamount You would be better off subclassing Decimal and then just overloading the methods you want to use. 你会过得更好继承Decimal ,然后就超载要使用的方法。

For example, you can create a method to check the type of another object and pass it to Amount if it is not an instance of Decimal . 例如,您可以创建一个方法来检查另一个对象的类型,如果它不是Decimal的实例,则将其传递给Amount Then overloading the __add__ and __radd__ methods allows the Amount object accept polymorphic addition. 然后,重载__add____radd__方法将使Amount对象接受多态加法。

from collections.abc import Iterable
from decimal import Decimal

class Amount(Decimal):
    def __repr__(self):
        return "Amount({})".format(self.__float__())

    def _checkset(self, other):
        if isinstance(other, Decimal):
            return other
        if isinstance(other, Iterable):
            return Amount(other[0])
        return Amount(other)

    def __add__(self, other):
        return self.__class__(super().__add__(self._checkset(other)))

    def __radd__(self, other):
        return self + other

a = Amount(1.2)

a + .4
# returns:
Amount(1.5999999999999999)

1 + a
# returns:
Amount(2.2)

# in your code, iterables only take the first object
a + [2, 3, 4]
# returns:
Amount(3.2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM