deepcopy
z copy
nie kopiuje klasę:Jak skopiować klasę python?
>>> class A(object):
>>> ARG = 1
>>> B = deepcopy(A)
>>> A().ARG
>>> 1
>>> B().ARG
>>> 1
>>> A.ARG = 2
>>> B().ARG
>>> 2
Czy to jedyny sposób?
B(A):
pass
deepcopy
z copy
nie kopiuje klasę:Jak skopiować klasę python?
>>> class A(object):
>>> ARG = 1
>>> B = deepcopy(A)
>>> A().ARG
>>> 1
>>> B().ARG
>>> 1
>>> A.ARG = 2
>>> B().ARG
>>> 2
Czy to jedyny sposób?
B(A):
pass
Ogólnie rzecz biorąc, dziedziczenie to właściwa droga, jak wskazały inne plakaty.
Jednakże, jeśli naprawdę chcesz, aby odtworzyć ten sam typ z inną nazwą i bez dziedziczenia następnie można zrobić to tak:
class B(object):
x = 3
CopyOfB = type('CopyOfB', B.__bases__, dict(B.__dict__))
b = B()
cob = CopyOfB()
print b.x # Prints '3'
print cob.x # Prints '3'
b.x = 2
cob.x = 4
print b.x # Prints '2'
print cob.x # Prints '4'
Trzeba być ostrożnym z modyfikowalnych wartości atrybutu:
class C(object):
x = []
CopyOfC = type('CopyOfC', C.__bases__, dict(C.__dict__))
c = C()
coc = CopyOfC()
c.x.append(1)
coc.x.append(2)
print c.x # Prints '[1, 2]' (!)
print coc.x # Prints '[1, 2]' (!)
Czy dict skopiowanej klasy jest powiązany z dict klasy, która została stworzona jako pierwsza? – I159
@ I159: To zależy od wartości w '__dict__'. Atrybuty nieprzemienne są w porządku, ale zmienne wartości atrybutów (takie jak listy) lub mechanizmy tła nowych klas stylów (np. Deskryptorów) prawdopodobnie Cię ugryzą. –
Działa to dobrze tylko wtedy, gdy atrybutowi "x" przypisano typ niezmienny, a nie zmienny, ponieważ 'dict (C .__ dict __)' robi tylko płytką kopię, a nie głębię. – hynekcer
Właściwy sposób "kopia" klasa, jest, jak przypuszczenie, dziedziczenie:
class B(A):
pass
Możesz także zrobić używając 'type()', np. 'B = typ (" B ", (A,), {})' – kindall
Dziedziczenie nie robi tego, co jest wymagane (induspendence wartości ARG), chyba że wartość jest również przypisana do B.ARG. – hynekcer
@hynecker: czy mógłbyś wyjaśnić, co przez to rozumiesz? Myślę, że to odpowiada na pytanie OP: –
Jeśli chcesz utworzyć tylko kolejną instancję klasy, a następnie po prostu zrobić to:
>>> class A(object):
... ARG=1
...
>>> a = A()
>>> A().ARG
1
>>> b = A()
>>> b.ARG
1
>>> a.ARG=2
>>> b.ARG
1
Stwórz własną konstruktora i po prostu powielić jak dokonaniu oryginalnego klasa:
class MyClass(object):
def __init__(self, **kw):
self.kw = kw
self.__dict__.update(kw)
def copy(self):
return MyClass(**self.kw)
Próbowałbym jednak uniknąć konieczności kopiowania obiektów.
sidenote: Użytkownik może również być w stanie uciec z robieniem:
B = deepcopy(A)
B.__dict__ = deepcopy(A.__dict__)
Ale to jest chyba bardzo źle i nie należy tego robić. edit: faktycznie AttributeError: 'dictproxy' object has no attribute 'update'
według PO
Właściwie obiekt 'AttributeError: 'dictproxy' nie ma atrybutu 'update'' – I159
Można użyć funkcji fabrycznego:
def get_A():
class A(object):
ARG = 1
return A
A = get_A()
B = get_A()
myślę, że rozumieją znaczenie zmiennej statycznej tutaj. Każde miejsce, w którym zadeklarujesz zmienną poza metodą, a nie w postaci self.some_thing
, zmienna będzie traktowana jako zmienna statyczna klasy (np. Twoja zmienna ARG tutaj). Zatem każdy obiekt (instancja) klasy, która zmienia zmienną statyczną, spowoduje zmianę wszystkich innych obiektów w tej samej klasie. Głębokość naprawdę spełnia tę funkcję.
Uwaga: poprawne pytanie brzmi: "Jak skopiować instancję klasy Pythona lub obiekt Pythona", a nie samą klasę Pythona. –
W rzeczywistości, Pavel, wygląda na to, że I159 rzeczywiście chce skopiować klasę. –
Nie wspominając już o tym, że w Pythonie klasa jest po prostu kolejnym obiektem, ale z dziwnym atrybutem '__dict__'. –