एक उदाहरण का वर्ग नाम प्राप्त करना?


1435

मुझे उस कक्षा का नाम कैसे पता चलेगा जिसने पायथन में किसी वस्तु का एक उदाहरण बनाया है यदि मैं जिस फ़ंक्शन से यह कर रहा हूं वह आधार वर्ग है जिसमें से उदाहरण का वर्ग व्युत्पन्न किया गया है?

सोच रहा था कि शायद इंस्पेक्ट मॉड्यूल ने मुझे यहां लाने में मदद की होगी, लेकिन यह मुझे ऐसा नहीं लगता जो मुझे चाहिए। और __class__सदस्य को पार्स करने से कम , मुझे यकीन नहीं है कि इस जानकारी को कैसे प्राप्त किया जाए।


क्या आप वास्तव में वर्ग चर से 'पार्स' कर रहे हैं ?
sykora

1
उस वर्ग का शीर्ष-स्तरीय नाम जिसका उदाहरण (मॉड्यूल नाम, आदि के बिना ...) से है
Dan

मुझे लगता है कि इसके विपरीत तरीका कठिन होगा (उस वर्ग को प्राप्त करने के लिए जिसमें विधि / कार्य परिभाषित है)।
एलेक्सी

जवाबों:


1906

क्या आपने कक्षा की __name__विशेषता को आजमाया है ? यानी type(x).__name__आपको उस वर्ग का नाम दिया जाएगा, जो मुझे लगता है कि आप जो चाहते हैं।

>>> import itertools
>>> x = itertools.count(0)
>>> type(x).__name__
'count'

यदि आप अभी भी पायथन 2 का उपयोग कर रहे हैं, तो ध्यान दें कि उपरोक्त विधि केवल नई शैली की कक्षाओं के साथ काम करती है (पायथन 3+ में सभी कक्षाएं "नई शैली की कक्षाएं" हैं)। आपका कोड कुछ पुरानी शैली की कक्षाओं का उपयोग कर सकता है। निम्नलिखित दोनों के लिए काम करता है:

x.__class__.__name__

40
आश्चर्यजनक रूप से सरल। आश्चर्य है कि dir(x.__class__)इसे सूचीबद्ध क्यों नहीं किया गया?
cfi

43
क्यों उपयोग __class__से अधिक typeविधि? इसलिए जैसा: type(x).__name__। डबल अंडरस्कोर सदस्यों को सीधे हतोत्साहित नहीं कर रहा है? मैं एक रास्ता नहीं देख सकता का उपयोग कर __name__, यद्यपि।
jpmc26

25
आपको __class__पुरानी शैली की कक्षाओं के साथ संगत होने के लिए सीधे उपयोग करना होगा, क्योंकि उनका प्रकार बस है instance
क्वांटम

14
यह अक्सर लॉगिंग, ऑर्म् और फ्रेमवर्क कोड में पर्याप्त रूप से उपयोग किया जाता है कि वास्तव में एक बेसिन टाइपनेम (x) होना चाहिए ... एक उपयोगकर्ता को "हिम्मत" देखने के लिए एक नाम प्राप्त करने की आवश्यकता होती है जो कि बहुत ही आकर्षक नहीं है, IMO।
एरिक एरोनिटी

5
@ एरिकॉनस्टी,def typename(x): return type(x).__name__
स्लीब्लांक

388

क्या आप एक स्ट्रिंग के रूप में कक्षा का नाम चाहते हैं?

instance.__class__.__name__

6
या उदाहरण .__ class__ क्लास की वस्तु पाने के लिए: D
पेन्सिलचेक

8
क्या डबल अंडरस्कोर गुणों का उपयोग करना सुरक्षित है?
एडुआर्ड लुका

5
@EduardLuca क्यों सुरक्षित नहीं होगा? अंतर्निहित गुण अंडरस्कोर का उपयोग करते हैं ताकि वे आपके द्वारा लिखे गए कोड के साथ किसी भी संघर्ष का कारण न
बनें

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

28
@EduardLuca शुरुआत में डबल अंडरस्कोर केवल शुरुआत में एक एकल अंडरस्कोर के समान हैं, लेकिन इससे भी अधिक "निजी" ("पायथन नाम मैनलिंग" देखें)। शुरुआत और अंत में डबल अंडरस्कोर अलग होते हैं - वे अजगर के लिए आरक्षित होते हैं और निजी नहीं होते हैं (जैसे __init__ और __add__ जैसे जादू के तरीके)।
लीगासैद गॉर्डन

100

प्रकार() ?

>>> class A(object):
...    def whoami(self):
...       print type(self).__name__
...
>>>
>>> class B(A):
...    pass
...
>>>
>>>
>>> o = B()
>>> o.whoami()
'B'
>>>

यह कक्षा के सदस्य के समान है , लेकिन मुझे इस परिणाम को हाथ से छोड़ना होगा, जो थोड़ा कष्टप्रद है ...
दान

8
मैं यह पसंद है। इस तरह, उपवर्ग का नाम प्राप्त करने के लिए एक आधार वर्ग में संभव है।
जौक्टी

6
या self.__class__.__name__इसके बजाय type(self).__name__एक ही व्यवहार पाने के लिए। जब तक कुछ ऐसा नहीं होता है जब तक type()मुझे पता नहीं चल जाता है?
andreb

2
आप उपयोग कर रहे हैं type(item)परिणाम सूची आइटम पर होगा <type 'instance'>, जबकि item.__class__.__name__वर्ग के नाम रखती है।
ग्रोचन

1
मुझे लगता है कि @Grochni उल्लेख केवल Python 2.x में कुछ वर्गों के लिए प्रासंगिक है, यहां देखें: stackoverflow.com/questions/6666856/…
Nate CK

43
class A:
  pass

a = A()
str(a.__class__)

नमूना कोड ऊपर (जब इंटरएक्टिव इंटरप्रेटर में इनपुट) का '__main__.A'विरोध किया जाएगा, 'A'जिसका उत्पादन __name__विशेषता के लागू होने पर किया जाता है। बस का परिणाम में उत्तीर्ण होकर A.__class__करने के लिए strनिर्माता पार्स आप के लिए नियंत्रित किया जाता है। हालाँकि, यदि आप कुछ अधिक स्पष्ट चाहते हैं, तो आप निम्न कोड का भी उपयोग कर सकते हैं।

"{0}.{1}".format(a.__class__.__module__,a.__class__.__name__)

यह व्यवहार बेहतर हो सकता है यदि आपके पास अलग-अलग मॉड्यूल में परिभाषित समान नाम के साथ कक्षाएं हों।

ऊपर दिया गया नमूना कोड पाइथन 2.7.5 में परीक्षण किया गया था।


2.6.6 में परीक्षण किया गया। फिर भी अच्छा काम करता है।
हैमलेट

29
type(instance).__name__ != instance.__class__.__name  #if class A is defined like
class A():
   ...

type(instance) == instance.__class__                  #if class A is defined like
class A(object):
  ...

उदाहरण:

>>> class aclass(object):
...   pass
...
>>> a = aclass()
>>> type(a)
<class '__main__.aclass'>
>>> a.__class__
<class '__main__.aclass'>
>>>
>>> type(a).__name__
'aclass'
>>>
>>> a.__class__.__name__
'aclass'
>>>


>>> class bclass():
...   pass
...
>>> b = bclass()
>>>
>>> type(b)
<type 'instance'>
>>> b.__class__
<class __main__.bclass at 0xb765047c>
>>> type(b).__name__
'instance'
>>>
>>> b.__class__.__name__
'bclass'
>>>

5
यह केवल पुराने पायथन 2.x के लिए सही है। 3.x में, bclass () bclass (ऑब्जेक्ट) को हल करेगा। और फिर भी, पायथन 2.2 में नई कक्षाएं दिखाई दीं।
alcalde

16

अच्छा प्रश्न।

यहाँ GHZ पर आधारित एक सरल उदाहरण है जो किसी की मदद कर सकता है:

>>> class person(object):
        def init(self,name):
            self.name=name
        def info(self)
            print "My name is {0}, I am a {1}".format(self.name,self.__class__.__name__)
>>> bob = person(name='Robert')
>>> bob.info()
My name is Robert, I am a person

13

वैकल्पिक रूप से आप classmethodडेकोरेटर का उपयोग कर सकते हैं :

class A:
    @classmethod
    def get_classname(cls):
        return cls.__name__

    def use_classname(self):
        return self.get_classname()

उपयोग :

>>> A.get_classname()
'A'
>>> a = A()
>>> a.get_classname()
'A'
>>> a.use_classname()
'A'

10

विशेष __name__विशेषता को हथियाने के अलावा , आप किसी दिए गए वर्ग / कार्य के लिए योग्य नाम की आवश्यकता के लिए खुद को पा सकते हैं । यह प्रकारों को हथियाने के द्वारा किया जाता है__qualname__

ज्यादातर मामलों में, ये बिल्कुल समान होंगे, लेकिन, जब आपको प्राप्त आउटपुट में नेस्टेड वर्गों / विधियों के साथ ये भिन्न होते हैं। उदाहरण के लिए:

class Spam:
    def meth(self):
        pass
    class Bar:
        pass

>>> s = Spam()
>>> type(s).__name__ 
'Spam'
>>> type(s).__qualname__
'Spam'
>>> type(s).Bar.__name__       # type not needed here
'Bar'
>>> type(s).Bar.__qualname__   # type not needed here 
'Spam.Bar'
>>> type(s).meth.__name__
'meth'
>>> type(s).meth.__qualname__
'Spam.meth'

आत्मनिरीक्षण के बाद से आप क्या कर रहे हैं, यह हमेशा आप पर विचार करना चाहते हो सकता है।


2
ध्यान दिया जाना चाहिए कि __qualname__पायथन 3.3+ के लिए है
फायरएफ़िस

10
और मैं अपने सॉफ्टवेयर "मेथ" में कुछ भी नाम रखने से बचूंगा।
बोबार्ट

__qualname__बनाम के लिए संबंधित स्पष्टीकरण __name__: stackoverflow.com/questions/58108488/what-is-qualname-in-python
ti7

0

उदाहरण प्राप्त करने के लिए classname:

type(instance).__name__

या

instance.__class__.__name__

दोनों समान हैं

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