वर्तमान कक्षा का नाम बताएं?


102

मैं वर्तमान में जिस कक्षा में हूं, उसका नाम कैसे मिलता है?

उदाहरण:

def get_input(class_name):
    [do things]
    return class_name_result

class foo():
    input = get_input([class name goes here])

कार्यक्रम की प्रकृति के कारण मैं (विस्ट्रिल्स) के साथ हस्तक्षेप कर रहा हूं, मैं __init__()इनिशियलाइज़ करने के लिए उपयोग नहीं कर सकता input

जवाबों:


158

obj.__class__.__name__ आपको कोई भी ऑब्जेक्ट नाम मिलेगा, इसलिए आप ऐसा कर सकते हैं:

class Clazz():
    def getName(self):
        return self.__class__.__name__

उपयोग:

>>> c = Clazz()
>>> c.getName()
'Clazz'

1
यह स्वीकृत उत्तर क्यों नहीं है? संपादित करें: ओके ओपी का दायरा आंतरिक नहीं है, यह कक्षा स्तर पर है।
कोमोडोवेव 12

6
@KomodoDave, क्योंकि यह गलत है, यहां तक ​​कि विधि के दायरे में भी। जब आप getNameचाइल्ड क्लास से कॉल करेंगे तो यह चाइल्ड क्लास के नाम को आउटपुट करेगा। यह तब मुश्किल हो जाता है यदि आप वास्तव में उस वर्ग को चाहते हैं जिसके साथ आप काम कर रहे हैं।
केनट जर्वेट

@KenetJervet का मतलब है कि जब आप मूल वर्ग getNameसे बुलाते हैं तो यह बच्चे के नाम का उत्पादन करेगा? ठीक है कि बाहर इशारा करने के लिए ty।
कोमोडावेव

5
OO- शब्दों में, समाधान (वास्तविक रनटाइम चाइल्ड क्लास नाम लौटाता है, भले ही getName()विधि सुपरक्लास में परिभाषित की गई हो) सही है।
sxc731

22

किसी वर्ग के शरीर के भीतर, वर्ग नाम अभी तक परिभाषित नहीं है, इसलिए यह उपलब्ध नहीं है। क्या आप केवल कक्षा का नाम नहीं लिख सकते हैं? हो सकता है कि आपको समस्या के बारे में अधिक कहने की आवश्यकता है ताकि हम आपके लिए एक समाधान पा सकें।

मैं आपके लिए यह काम करने के लिए एक मेटाक्लस बनाऊंगा। यह वर्ग निर्माण समय (वैचारिक रूप से कक्षा के बहुत अंत में: ब्लॉक) पर लागू किया जाता है, और बनाई जा रही कक्षा में हेरफेर कर सकता है। मैंने इसका परीक्षण नहीं किया है:

class InputAssigningMetaclass(type):
    def __new__(cls, name, bases, attrs):
        cls.input = get_input(name)
        return super(MyType, cls).__new__(cls, name, bases, newattrs)

class MyBaseFoo(object):
    __metaclass__ = InputAssigningMetaclass

class foo(MyBaseFoo):
    # etc, no need to create 'input'

class foo2(MyBaseFoo):
    # etc, no need to create 'input'

यह स्पष्ट करने के लिए कि मैं क्या करने की कोशिश कर रहा हूं: मुझे एक विधि के बाहर एक वर्ग चर, 'इनपुट' बनाने और शुरू करने की आवश्यकता है । मेरे पास छोटी कक्षाओं का एक समूह है, जिनमें से प्रत्येक को पैरामीटर के रूप में अपने वर्ग के नाम का उपयोग करके 'get_input' कहना चाहिए। मैं इसे सामान्य करने की कोशिश कर रहा हूं, इसलिए मुझे प्रत्येक कक्षा में नहीं जाना होगा (वहाँ 100 या तो होगा) और कक्षा के नाम पर टाइप करें।
जोनाथन जिन्सबर्ग

ठीक है, मैंने अपना उत्तर एक मेटाक्लस के साथ अपडेट किया है जो मदद करनी चाहिए।
नेड बाचेल्ड

1
क्या करता है MyTypeमें superलाइन में InputAssigningMetaclassउल्लेख करने के लिए?
22

16

आप इसे कक्षा की निजी विशेषताओं द्वारा एक्सेस कर सकते हैं:

cls_name = self.__class__.__name__

संपादित करें:

जैसा कि कहा गया है Ned Batcheler, यह वर्ग निकाय में काम नहीं करेगा, लेकिन यह एक विधि में होगा।


11

PEP 3155 पेश __qualname__किया गया, जिसे पायथन 3.3 में लागू किया गया था।

शीर्ष स्तर के कार्यों और वर्गों के लिए, __qualname__विशेषता विशेषता के बराबर है __name__। नेस्टेड वर्गों, विधियों, और नेस्टेड फ़ंक्शन के लिए, __qualname__विशेषता में मॉड्यूल शीर्ष-स्तर से ऑब्जेक्ट पर जाने वाला एक बिंदीदार पथ होता है।

यह वर्ग या फ़ंक्शन की बहुत परिभाषा के भीतर से सुलभ है, इसलिए उदाहरण के लिए:

class Foo:
    print(__qualname__)

प्रभावी ढंग से प्रिंट होगा Foo। आपको पूरी तरह से योग्य नाम (मॉड्यूल के नाम को छोड़कर) मिलेगा, ताकि आप इसे .चरित्र पर विभाजित करना चाहें ।

हालांकि, परिभाषित किए जा रहे वर्ग पर एक वास्तविक संभाल पाने का कोई तरीका नहीं है।

>>> class Foo:
...     print('Foo' in globals())
... 
False

7

संपादित करें: हाँ, आप कर सकते हैं; लेकिन आपको धोखा देना होगा: वर्तमान में चल रहा वर्ग नाम कॉल स्टैक पर मौजूद है, और tracebackमॉड्यूल आपको स्टैक तक पहुंचने की अनुमति देता है।

>>> import traceback
>>> def get_input(class_name):
...     return class_name.encode('rot13')
... 
>>> class foo(object):
...      _name = traceback.extract_stack()[-1][2]
...     input = get_input(_name)
... 
>>> 
>>> foo.input
'sbb'

हालाँकि, मैं ऐसा नहीं करूँगा; मेरे मूल उत्तर अभी भी समाधान के रूप में मेरी अपनी प्राथमिकता है। मूल उत्तर:

शायद सबसे सरल समाधान एक डेकोरेटर का उपयोग करना है, जो नेड के उत्तर के समान है, जिसमें मेटाक्लासेस शामिल हैं, लेकिन कम शक्तिशाली (डेकोरेटर काले जादू करने में सक्षम हैं, लेकिन मेटाकालेज़ प्राचीन, मनोगत काले जादू में सक्षम हैं )

>>> def get_input(class_name):
...     return class_name.encode('rot13')
... 
>>> def inputize(cls):
...     cls.input = get_input(cls.__name__)
...     return cls
... 
>>> @inputize
... class foo(object):
...     pass
... 
>>> foo.input
'sbb'
>>> 

1
import sys

def class_meta(frame):
    class_context = '__module__' in frame.f_locals
    assert class_context, 'Frame is not a class context'

    module_name = frame.f_locals['__module__']
    class_name = frame.f_code.co_name
    return module_name, class_name

def print_class_path():
    print('%s.%s' % class_meta(sys._getframe(1)))

class MyClass(object):
    print_class_path()

1

मुझे लगता है, यह इस तरह होना चाहिए:

    class foo():
        input = get_input(__qualname__)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.