বর্তমান শ্রেণীর নাম পাবেন?


103

আমি বর্তমানে যে ক্লাসে রয়েছি তার নাম কীভাবে পাব?

উদাহরণ:

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

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

প্রোগ্রামটির প্রকৃতির কারণে আমি (ভিস্ট্রেইলস) এর সাথে ইন্টারফেস করছি, আমি __init__()আরম্ভ করতে ব্যবহার করতে পারি না input

উত্তর:


159

obj.__class__.__name__ আপনার কোনও বস্তুর নাম পাবেন, যাতে আপনি এটি করতে পারেন:

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

ব্যবহার:

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

4
কেন এটি গৃহীত উত্তর নয়? সম্পাদনা: ঠিক আছে ওপির সুযোগটি অভ্যন্তরীণ নয়, এটি শ্রেণির স্তরে।
কমডোডেভ

6
@ কমোডো ডেভ, কারণ পদ্ধতিটি ক্ষেত্রেও এটি ভুল। আপনি যখন getNameকোনও শিশু শ্রেণি থেকে কল করবেন তখন এটি শিশু শ্রেণীর নাম আউটপুট করবে। এটি তখন জটিল হয়ে ওঠে যদি আপনি সত্যিই আপনি যে শ্রেণীর সাথে কাজ করছেন তা চান।
কেনেট জেরভেট

@ কেনেট জারভেট মানে আপনি যখন getNameকোনও পিতামাতার ক্লাস থেকে কল করবেন তখন এটি শিশু শ্রেণীর নাম আউটপুট দেবে? এটি নির্দেশ করার জন্য ঠিক আছে।
কমডোডেভ

5
ওও-পদগুলিতে, সমাধানটি ( 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 বা তার বেশি হবে) এবং ক্লাসের নামে টাইপ করতে হবে।
জোনাথন গিন্সবার্গ 4'11

ঠিক আছে, আমি আমার উত্তরটি একটি মেটাক্লাস দিয়ে আপডেট করেছি যাতে সহায়তা করা উচিত।
নেড ব্যাচেল্ডার

4
কি MyTypeমধ্যে superলাইনে InputAssigningMetaclassপড়ুন?
এ।

16

আপনি শ্রেণীর ব্যক্তিগত বৈশিষ্ট্য দ্বারা এটি অ্যাক্সেস করতে পারেন:

cls_name = self.__class__.__name__

সম্পাদনা:

যেমনটি বলা হয়েছে Ned Batcheler, এটি শ্রেণিবদ্ধ কাজ করবে না, তবে এটি একটি পদ্ধতিতে হবে।


12

পিইপি 3155 প্রবর্তিত __qualname__, যা পাইথন ৩.৩ এ প্রয়োগ করা হয়েছিল।

শীর্ষ-স্তরের ফাংশন এবং ক্লাসগুলির জন্য, __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()

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.