2012-05-17 6 views
8

मुझे इस तरह के प्रश्नों के समान एहसास हुआ है, हालांकि बिल्कुल इस तरह से नहीं।क्या अजगर में एक प्रतिलिपि बनाने वाला कोई अच्छा तरीका है?

मैं अपनी कक्षा के निर्माता के लिए एक वैकल्पिक तर्क लेना चाहता हूं कि, यदि यह मेरी कक्षा का एक उदाहरण है, तो इसकी प्रतिलिपि बनाई जाएगी। उदाहरण के लिए, कुछ की तरह (मैं जानता हूँ कि इस कोड काम नहीं करता है!):

class Foo(object): 
    def __init__(self, foo=None): 
     self.x = None 
     self.y = None 
     self.z = None 

     if foo is not None and isinstance(foo, Foo): 
      self = copy.deepcopy(foo) 

a = Foo() 
a.x = 1 
a.y = 2 
a.z = 3 

b = Foo(a) 
print b.x 
print b.y 
print b.z 

मैं जानता हूँ कि यह करने के लिए कुछ व्यावहारिक समाधान नहीं है। मैं foo की इसी विशेषता के मूल्य के अनुसार स्वयं की प्रत्येक विशेषता सेट कर सकता हूं, लेकिन यह वास्तव में परेशान होगा क्योंकि मेरी कक्षा में कई, कई विशेषताएं हैं। या मैं बस उपयोग कर सकता था:

b = copy.deepcopy(a) 

... लेकिन अगर यह संभव है तो मैं नहीं चाहूंगा। मैं __new__ ओवरराइडिंग से बचने की भी उम्मीद कर रहा हूं।

क्या कोई कॉपी कन्स्ट्रक्टर बनाने के लिए पाइथन में वास्तव में कोई सभ्य तरीका नहीं है?

+3

क्यों नहीं करते आप बी = copy.deepcopy (ए) का उपयोग करना चाहते हैं? मेरा मतलब है, अगर यह काम करता है, और यह बी = फू (ए) से लिखने के लिए और अधिक लाइन नहीं लेता है .... – DGH

+0

ठीक है, मुझे लगता है कि मेरी उंगलियां अभी भी पार हो गई हैं कि एक प्रतिलिपि बनाने योग्य है। और स्पष्ट रूप से, यह क्यों नहीं है? ऐसा नहीं है कि यह वास्तव में असामान्य अनुरोध है। कोई सोचता है कि सभी ऑब्जेक्ट उन्मुख भाषाओं में यह सुविधा होगी। – carmenism

+1

यह सुविधा क्यों नहीं है? क्योंकि यह सिर्फ वाक्य रचनात्मक चीनी है, बिल्कुल वही बात कहने का एक अलग तरीका है। जब तक कार्यक्षमता कोड की केवल एक बहुत ही सरल रेखा के साथ गहरी प्रतिलिपि बनाने के लिए मौजूद है, तो यह क्यों मायने रखता है कि यह "कन्स्ट्रक्टर" है या नहीं? – DGH

उत्तर

16

मुझे लगता है कि यह करने का यह सबसे महत्वपूर्ण तरीका है - एक प्रति कारखाना विधि।

import copy 

class Foo(object): 
    def __init__(self): 
     self.x = None 
     self.y = None 
     self.z = None 
    def copy(self): 
     return copy.deepcopy(self) 

a = Foo() 
a.x = 1 
a.y = 2 
a.z = 3 

b = a.copy() 
print b.x 
print b.y 
print b.z 

यह अजगर बुनियादी प्रकार में काफी आम है (उदाहरण के dict.copy)। यह एक प्रतिलिपि निर्माता नहीं है, लेकिन मुझे नहीं लगता कि यह एक बहुत ही पाइथनिक अवधारणा है!

+0

यह एक और विचार था जिसे मैं अपने प्रश्न में उल्लेख करना भूल गया था। मुझे यह कम से कम b = copy.deepcopy (ए) से अधिक पसंद है। धन्यवाद! – carmenism

0

ऐसा नहीं है कि आप सिर्फ स्रोत ऑब्जेक्ट __init__ के लिए पारित पर सभी विशेषताओं से अधिक पुनरावृति कर सकते हैं संभव है, है, और फिर setattr() जिन्हें आप पर self के बारे में परवाह। लेकिन यह बिल्कुल स्पष्ट नहीं है कि यह समस्या हल करने का एक अच्छा तरीका होगा। बहुत पाइथनिक नहीं, और सब कुछ।

+0

मैंने इसके बारे में भी सोचा, लेकिन यह वास्तव में बहुत पाइथनिक प्रतीत नहीं होता है। फिर भी धन्यवाद। – carmenism

0

ऐसा करने का एक अच्छा तरीका उदाहरण के नामस्थान की शीर्ष-स्तरीय प्रति बनाना है।

class Tst: 
    def __init__(self, somearg): 
     if isinstance(somearg, self.__class__): 
      self.__dict__ = somearg.__dict__.copy() 
     else: 
      self.var = somearg 
    def echo(self): 
     print(self.var) 

a = Tst(123) 
b = Tst(456) 
a.echo()  # gives 123 
b.echo()  # gives 456 
c = Tst(a) 
c.echo()  # gives 123 
c.var is a.var # gives False -> different objects 

लेकिन __slots__ के साथ अपने वर्ग सौदों अगर सावधान रहना होगा, क्योंकि उस मामले में __dict__ अनुपस्थित हो सकता है और इस प्रकार आप अधिक तटस्थ विशेषता-हो रही तंत्र पर भरोसा करने की आवश्यकता हो सकती है, इस तरह के रूप getattr()

संबंधित मुद्दे

 संबंधित मुद्दे