अजगर: निर्धारित करता है, तो एक वर्ग नीडिंत है

वोट
5

मान लीजिए आप एक अजगर विधि पैरामीटर के रूप में एक प्रकार हो जाता है; यह निर्धारित करने के लिए दिए गए प्रकार एक नेस्टेड वर्ग है संभव है?
इस उदाहरण में उदाहरण के लिए:

def show_type_info(t):
    print t.__name__
    # print outer class name (if any) ...

class SomeClass:
    pass

class OuterClass:
    class InnerClass:
        pass

show_type_info(SomeClass)
show_type_info(OuterClass.InnerClass)

मैं कॉल की तरह करने के लिए show_type_info(OuterClass.InnerClass)भी पता चलता है कि InnerClass OuterClass अंदर परिभाषित किया गया है।

12/03/2009 को 16:26
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


6 जवाब

वोट
12

AFAIK, एक वर्ग और कोई अन्य जानकारी दी, आपको बता नहीं सकता है या नहीं, यह एक नेस्टेड वर्ग है। हालांकि, यहाँ देखें कैसे आप एक डेकोरेटर का उपयोग कर सकते यह निर्धारित करने के लिए।

समस्या यह है कि एक नेस्टेड वर्ग बस एक सामान्य वर्ग इसकी बाहरी वर्ग की एक विशेषता यह है कि है। अन्य समाधान है कि आप शायद काम करने के लिए उम्मीद कर सकते हैं नहीं होगा - inspect.getmroउदाहरण के लिए, केवल आप आधार वर्ग, नहीं बाहरी कक्षाओं देता है।

इसके अलावा, नेस्टेड कक्षाएं शायद ही कभी की जरूरत है। मैं दृढ़ता से पुनर्विचार होता है कि प्रत्येक विशेष मामले ऐसे हैं जिनमें से एक का उपयोग करने के लिए परीक्षा महसूस में एक अच्छा तरीका है या नहीं।

12/03/2009 को 16:34
का स्रोत उपयोगकर्ता

वोट
5

एक आंतरिक वर्ग पायथन में कोई विशेष विशेष सुविधाओं प्रदान करता है। यह केवल वर्ग वस्तु, एक पूर्णांक या स्ट्रिंग संपत्ति से अलग नहीं की संपत्ति है। आपका OuterClass / InnerClass उदाहरण बिल्कुल के रूप में फिर से लिखा जा सकता है:

class OuterClass(): pass
class InnerClass(): pass
OuterClass.InnerClass= InnerClass

InnerClass, पता नहीं कर सकते हैं कि क्या यह एक और वर्ग के अंदर घोषित किया गया था, क्योंकि वह सिर्फ एक सादे बाध्यकारी चर है। जादू करता है कि बाध्य तरीकों अपने मालिक 'स्वयं' के बारे में पता यहाँ लागू नहीं होता।

लिंक में innerclass डेकोरेटर जादू जॉन तैनात एक दिलचस्प दृष्टिकोण है, लेकिन के रूप में है मैं इसका इस्तेमाल नहीं होता। यह कक्षाएं यह प्रत्येक बाहरी वस्तु के लिए बनाता है कैश नहीं है, इसलिए यदि आप एक नए InnerClass हर बार जब आप outerinstance.InnerClass फोन मिलता है:

>>> o= OuterClass()
>>> i= o.InnerClass()
>>> isinstance(i, o.InnerClass)
False # huh?
>>> o.InnerClass is o.InnerClass
False # oh, whoops...

इसके अलावा जिस तरह से यह बाहरी वर्ग चर getattr / setattr के साथ आंतरिक वर्ग पर उपलब्ध कराने की जावा व्यवहार को दोहराने की कोशिश करता है बहुत कुशल, और अनावश्यक वास्तव में (मैं बाहरी .__ के बाद से अधिक pythonic तरीका कॉल करने के लिए किया जाएगा ATTR स्पष्ट __।) है।

12/03/2009 को 17:23
का स्रोत उपयोगकर्ता

वोट
4

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

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

import inspect

def not_toplevel(cls):
    m = inspect.getmodule(cls)
    return not (getattr(m, cls.__name__, []) is cls)

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

class C:             # not_toplevel(C) = False
    class B: pass    # not_toplevel(C.B) = True

B=C.B                # not_toplevel(B) = True

D=C                  # D is defined at the top, but...
del C                # not_toplevel(D) = True

def getclass():      # not_toplevel(getclass()) = True
    class C: pass
12/03/2009 को 17:46
का स्रोत उपयोगकर्ता

वोट
1

आपके जवाबों के लिए आप सभी का धन्यवाद।
मैं यह संभव समाधान metaclasses का उपयोग कर पाया है; मैं इसे और अधिक वास्तविक आवश्यकता की तुलना में obstination के लिए किया है, और यह एक तरीका है कि अजगर 3. करने के लिए लागू नहीं होगा में किया है
मैं वैसे भी इस समाधान साझा करना चाहते हैं, तो मैं इसे यहाँ पोस्ट कर रहा हूँ।

#!/usr/bin/env python
class ScopeInfo(type): # stores scope information
    __outers={} # outer classes
    def __init__(cls, name, bases, dict):
        super(ScopeInfo, cls).__init__(name, bases, dict)
        ScopeInfo.__outers[cls] = None
        for v in dict.values(): # iterate objects in the class's dictionary
            for t in ScopeInfo.__outers:
                if (v == t): # is the object an already registered type?
                    ScopeInfo.__outers[t] = cls
                    break;
    def FullyQualifiedName(cls):
        c = ScopeInfo.__outers[cls]
        if c is None:
            return "%s::%s" % (cls.__module__,cls.__name__)
        else:
            return "%s.%s" % (c.FullyQualifiedName(),cls.__name__)

__metaclass__ = ScopeInfo

class Outer:
    class Inner:
        class EvenMoreInner:
            pass

print Outer.FullyQualifiedName()
print Outer.Inner.FullyQualifiedName()
print Outer.Inner.EvenMoreInner.FullyQualifiedName()
X = Outer.Inner
del Outer.Inner
print X.FullyQualifiedName()
12/03/2009 को 18:14
का स्रोत उपयोगकर्ता

वोट
0

अजगर 3.3 के साथ शुरुआत एक नई विशेषता है __qualname__, जो न केवल वर्ग के नाम, लेकिन यह भी बाहरी वर्गों के नाम प्रदान करता है:

अपने नमूने में यह परिणाम होगा:

assert SomeClass.__qualname__ == 'SomeClass'
assert OuterClass.InnerClass.__qualname__ == 'OuterClass.InnerClass'

यदि __qualname__का एक वर्ग एक में शामिल नहीं करता है '।' यह एक बाहरी वर्ग है!

22/04/2018 को 18:53
का स्रोत उपयोगकर्ता

वोट
0

आप इसे अपने आप को निर्धारित नहीं करते हैं, मैं नहीं मानता कि किसी भी तरह से करता है, तो वर्ग नीडिंत है निर्धारित करने के लिए नहीं है। वैसे भी एक अजगर वर्ग एक नाम स्थान (या कम से कम आसानी से नहीं) के रूप में इस्तेमाल नहीं किया जा सकता है, मैं कहूँगा कि ऐसा करने के लिए सबसे अच्छी बात बस है अलग फ़ाइलों का उपयोग करें।

12/03/2009 को 17:37
का स्रोत उपयोगकर्ता

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more