2011-08-04 23 views
66

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

उदाहरण:

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

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

कार्यक्रम मैं (vistrails) के साथ इंटरफ़ेस हूँ की प्रकृति के कारण, मैं __init__() उपयोग नहीं कर सकते input प्रारंभ करने में।

उत्तर

18

कक्षा के शरीर के भीतर, कक्षा का नाम अभी तक परिभाषित नहीं किया गया है, इसलिए यह उपलब्ध नहीं है। क्या आप बस कक्षा का नाम टाइप नहीं कर सकते? शायद आपको समस्या के बारे में और कुछ कहना है ताकि हम आपके लिए समाधान ढूंढ सकें।

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

cls_name = self.__class__.__name__ 

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

रूप Ned Batcheler से कहा, यह काम नहीं होगा

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' 
+0

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

+0

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

+0

'इनपुट एसिग्निटिंग मेटाक्लास' में 'सुपर' लाइन में' माईटाइप 'का क्या अर्थ है? –

12

आप वर्ग की निजी गुण तक पहुँच सकते हैं कक्षा के शरीर में, लेकिन यह एक विधि में होगा।

99

obj.__class__.__name__ आप किसी भी वस्तुओं नाम मिल जाएगा, तो आप ऐसा कर सकते हैं:

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

उपयोग:

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

यह स्वीकार्य उत्तर क्यों नहीं है? संपादित करें: ठीक ओपी का दायरा आंतरिक नहीं है, यह कक्षा स्तर पर है। – KomodoDave

+1

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

+0

@KenetJervet आपका मतलब है कि जब आप _parent_ कक्षा से 'getName' को कॉल करते हैं तो यह बाल वर्ग का नाम आउटपुट करेगा? उस बिंदु को इंगित करने के लिए ठीक है। – KomodoDave

7

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

>>> 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' 

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

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

>>> 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() 
संबंधित मुद्दे