2009-02-28 15 views
16

आइए कहें कि मेरे पास एक लाइब्रेरी फ़ंक्शन है जिसे मैं बदल नहीं सकता जो कक्षा ए के ऑब्जेक्ट का उत्पादन करता है, और मैंने ए क्लास बी बनाया है जो एकिसी ऑब्जेक्ट को पायथन में उप-वर्ग में परिवर्तित करना?

लाइब्रेरी फ़ंक्शन का उपयोग करने के लिए सबसे सरल तरीका है कक्षा बी का एक वस्तु?

संपादित मैं और अधिक विस्तार के लिए एक टिप्पणी में कहा गया था, इसलिए यहाँ जाता है:

PyTables एक पैकेज है कि अजगर में श्रेणीबद्ध डेटासेट संभालती है। जितना अधिक मैं उपयोग करता हूं वह उस डेटा को प्रबंधित करने की क्षमता है जो आंशिक रूप से डिस्क पर है। यह एक 'ऐरे' प्रकार प्रदान करता है जो केवल विस्तारित टुकड़े के साथ आता है, लेकिन मुझे मनमाने ढंग से पंक्तियों का चयन करने की आवश्यकता है। Numpy इस क्षमता की पेशकश करता है - आप उसी सरणी के एक बूलियन सरणी प्रदान करके चुन सकते हैं, जिस सरणी से आप चयन कर रहे हैं। इसलिए, मैं इस नई कार्यक्षमता को जोड़ने के लिए ऐरे को उप-वर्ग बनाना चाहता था।

यह एक अधिक सार अर्थ में एक समस्या मैं पहले विचार किया है। सामान्य समाधान जैसा कि पहले ही सुझाया गया है- बी के लिए एक कन्स्ट्रक्टर है जो ए और अतिरिक्त तर्क लेता है, और उसके बाद बी में डालने के लिए ए के प्रासंगिक बिट्स खींचता है क्योंकि यह काफी मूल समस्या की तरह लग रहा था, मैंने सवाल पूछने के लिए कहा यह देखने के लिए कि क्या कोई मानक समाधान था, मुझे पता नहीं था।

+0

आप कारण है कि आप क्या करना चाहते हैं पर और अधिक विस्तार किया जा सका इस? – Kiv

उत्तर

13

चूंकि लाइब्रेरी फ़ंक्शन ए को लौटाता है, इसलिए आप इसे बिना किसी बदलाव के बी को वापस नहीं कर सकते हैं।

एक बात आप कर सकते हैं एक उदाहरण के क्षेत्र में लेने के लिए एक समारोह लिखने और उन्हें एक नया बी उदाहरण में पर कॉपी है:

class A: # defined by the library 
    def __init__(self, field): 
     self.field = field 

class B(A): # your fancy new class 
    def __init__(self, field, field2): 
     self.field = field 
     self.field2 = field2 # B has some fancy extra stuff 

def b_from_a(a_instance, field2): 
    """Given an instance of A, return a new instance of B.""" 
    return B(a_instance.field, field2) 


a = A("spam") # this could be your A instance from the library 
b = b_from_a(a, "ham") # make a new B which has the data from a 

print b.field, b.field2 # prints "spam ham" 

संपादित करें: अपनी स्थिति पर निर्भर करता है, विरासत के बजाय रचना एक अच्छी शर्त हो सकती है; यह है कि आपकी बी कक्षा में विरासत के बजाय ए का एक उदाहरण हो सकता है:

class B2: # doesn't have to inherit from A 
    def __init__(self, a, field2): 
     self._a = a # using composition instead 
     self.field2 = field2 

    @property 
    def field(self): # pass accesses to a 
     return self._a.field 
    # could provide setter, deleter, etc 

a = A("spam") 
b = B2(a, "ham") 

print b.field, b.field2 # prints "spam ham" 
+3

पायथन ऑब्जेक्ट्स '.__ class__' विशेषता सेट करके अपनी कक्षा को जानते हैं। आप वास्तव में इसे किसी अन्य चीज़ पर सेट कर सकते हैं: http://stackoverflow.com/a/29256784/1423333 –

+0

मैं self._a से डेटा खींचने के लिए @property का उपयोग करके ऊपर उठ रहा हूं। संरचना खुद को शुद्ध विधियों को लिखने के लिए उधार देती है जो कि सबसे ज्यादा आसान है।विरासत गलत नहीं है और यह वास्तव में आपके उपयोग के मामले पर निर्भर करता है। लेकिन मेरा अनुभव कहता है कि संरचना लंबी अवधि से निपटने में आसान हो जाती है। – srock

1

लाइब्रेरी बंदरपैच?

उदाहरण के लिए,

import other_library 
other_library.function_or_class_to_replace = new_function 

Poof, यह रिटर्न जो भी आप इसे वापस करना चाहते हैं।

बंदरपैच ए नया बी के उदाहरण को वापस करने के लिए?

आप obj = ए() को कॉल करने के बाद, परिणाम ओबीजे बदलें। कक्षा = बी?

15

यह किया जा सकता है यदि उपclass के प्रारंभकर्ता इसे संभाल सकते हैं, या आप एक स्पष्ट उन्नयन लिखते हैं। यहाँ एक उदाहरण है:

class A(object): 
    def __init__(self): 
     self.x = 1 

class B(A): 
    def __init__(self): 
     super(B, self).__init__() 
     self._init_B() 
    def _init_B(self): 
     self.x += 1 

a = A() 
b = a 
b.__class__ = B 
b._init_B() 

assert b.x == 2 
3

आप वास्तव में वस्तु की .__class__ विशेषता बदल सकते हैं यदि आप जानते हैं कि तुम क्या कर रहे हो:

In [1]: class A(object): 
    ...:  def foo(self): 
    ...:   return "foo" 
    ...: 

In [2]: class B(object): 
    ...:  def foo(self): 
    ...:   return "bar" 
    ...: 

In [3]: a = A() 

In [4]: a.foo() 
Out[4]: 'foo' 

In [5]: a.__class__ 
Out[5]: __main__.A 

In [6]: a.__class__ = B 

In [7]: a.foo() 
Out[7]: 'bar' 
संबंधित मुद्दे

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