2009-08-20 10 views
9

ओब्जे-सी (जिसे मैंने लंबे समय तक उपयोग नहीं किया है) में कक्षाओं का विस्तार करने के लिए categories कहा जाता है। नई विधियों के साथ एक श्रेणी घोषित करना और इसे अपने प्रोग्राम में संकलित करना, कक्षा के सभी उदाहरणों में अचानक नई विधियां हैं।पायथन में Obj-C श्रेणियां कैसे करें?

पायथन में मिश्रित संभावनाएं हैं, जिनका मैं उपयोग करता हूं, लेकिन मिश्रण के कार्यक्रम से मिश्रण का उपयोग किया जाना चाहिए: कक्षा को इसे स्वयं घोषित करना है।

फोरसीन श्रेणी का उपयोग-मामला: कहें कि आपके पास एक बड़ी श्रेणी पदानुक्रम है जो डेटा के साथ बातचीत करने के विभिन्न तरीकों का वर्णन करता है, विभिन्न गुणों पर प्राप्त करने के लिए पॉलिमॉर्फिक तरीकों की घोषणा करता है। अब एक श्रेणी इन तरीकों तक पहुंचने के लिए एक सुविधाजनक इंटरफेस को लागू करके इन वर्णन वर्गों के उपभोक्ता की मदद कर सकती है। (उदाहरण के लिए एक श्रेणी विधि दो अलग-अलग तरीकों का प्रयास कर सकती है और पहले परिभाषित (गैर-कोई नहीं) वापसी मान वापस कर सकती है।)

पायथन में ऐसा करने का कोई तरीका?

व्याख्यात्मक कोड

मैं आशा इस स्पष्ट किया मैं क्या मतलब है। मुद्दा यह है कि श्रेणी एक समग्र इंटरफ़ेस की तरह है, कि AppObj का उपभोक्ता में कोड में बदल सकता है।

class AppObj (object): 
    """This is the top of a big hierarchy of subclasses that describe different data""" 
    def get_resource_name(self): 
    pass 
    def get_resource_location(self): 
    pass 

# dreaming up class decorator syntax 
@category(AppObj) 
class AppObjCategory (object): 
    """this is a category on AppObj, not a subclass""" 
    def get_resource(self): 
    name = self.get_resource_name() 
    if name: 
     return library.load_resource_name(name) 
    else: 
     return library.load_resource(self.get_resource_location()) 
+0

अपने उदाहरण में, आप AppObj या AppObjCategory का दृष्टांत हैं? बीटीडब्ल्यू पायथन में कक्षा सजावटकर्ता अब 2.6 में हैं: http://docs.python.org/whatsnew/2.6.html#pep-3129-class-decorators –

+0

मैं AppObj (और इसके सबक्लास) को तुरंत चालू करता हूं। श्रेणी कोड पूरी तरह से अलग हो सकता है (यानी AppObj लाइब्रेरी में हो सकता है, एप्लिकेशन में श्रेणी)। – u0b34a0f6ae

+0

शायद यह श्रेणी श्रेणी सजावट को लागू करने के लिए बस एक मामला है; श्रेणी से बेस क्लास में सभी विशेषताओं की प्रतिलिपि बनाएँ, जैसे कुछ विशेषताएं .. __doc__ और __dict__? – u0b34a0f6ae

उत्तर

2

मैं कक्षा सजावट के इस कार्यान्वयन के साथ आया था। मैं python2.5 का उपयोग कर रहा हूं इसलिए मैंने वास्तव में इसे सजावटी वाक्यविन्यास (जो अच्छा होगा) के साथ परीक्षण नहीं किया है, और मुझे यकीन नहीं है कि यह वास्तव में सही है। लेकिन यह इस तरह दिखता है:

pycategories.py

""" 
This module implements Obj-C-style categories for classes for Python 

Copyright 2009 Ulrik Sverdrup <[email protected]> 
License: Public domain 
""" 

def Category(toclass, clobber=False): 
    """Return a class decorator that implements the decorated class' 
    methods as a Category on the class @toclass 

    if @clobber is not allowed, AttributeError will be raised when 
    the decorated class already contains the same attribute. 
    """ 
    def decorator(cls): 
     skip = set(("__dict__", "__module__", "__weakref__", "__doc__")) 
     for attr in cls.__dict__: 
      if attr in toclass.__dict__: 
       if attr in skip: 
        continue 
       if not clobber: 
        raise AttributeError("Category cannot override %s" % attr) 
      setattr(toclass, attr, cls.__dict__[attr]) 
     return cls 
    return decorator 
8

क्यों न केवल विधियों को गतिशील रूप से जोड़ें?

>>> class Foo(object): 
>>>  pass 
>>> def newmethod(instance): 
>>>  print 'Called:', instance 
... 
>>> Foo.newmethod = newmethod 
>>> f = Foo() 
>>> f.newmethod() 
Called: <__main__.Foo object at 0xb7c54e0c> 

मुझे उद्देश्य-सी पता है और यह श्रेणियों की तरह दिखता है। एकमात्र कमी यह है कि आप इसे अंतर्निहित या विस्तार प्रकार के लिए नहीं कर सकते हैं।

+1

केवल अंतर यह है कि श्रेणी अधिक व्यवस्थित या स्पष्ट है, खासकर यदि आप पहले ही अवधारणा को जानते हैं। – u0b34a0f6ae

+0

मैं इस छोटी सी संबंधित सहायता को जोड़ना चाहूंगा: आप उस ऑब्जेक्ट पर '__class __.__ mro__' का उपयोग कर किसी ऑब्जेक्ट के सुपरक्लास प्राप्त कर सकते हैं। यह उपयोगी हो सकता है यदि आपके पास कई कक्षाएं हैं जिन्हें आप विधि जोड़ना चाहते हैं और उनके सामान्य सुपरक्लास की तलाश में हैं। – ArtOfWarfare

2

पायथन के setattr समारोह इस आसान बनाता है।

# categories.py 

class category(object): 
    def __init__(self, mainModule, override = True): 
     self.mainModule = mainModule 
     self.override = override 

    def __call__(self, function): 
     if self.override or function.__name__ not in dir(self.mainModule): 
      setattr(self.mainModule, function.__name__, function) 

 

# categories_test.py 

import this 
from categories import category 

@category(this) 
def all(): 
    print "all things are this" 

this.all() 
>>> all things are this 
संबंधित मुद्दे