현재 수업 이름을 얻으시겠습니까?


102

현재 수업 이름을 어떻게 알 수 있습니까?

예:

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

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

내가 (vistrails) 인터페이스하고있는 프로그램의 특성으로 인해을 (를) __init__()초기화 하는 데 사용할 수 없습니다 input.

답변:


158

obj.__class__.__name__ 개체 이름을 가져 오므로 다음과 같이 할 수 있습니다.

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

용법:

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

1
왜 이것이 허용되지 않는 대답입니까? 편집 : Ok OP의 범위는 내부가 아니며 클래스 수준입니다.
KomodoDave 2014

6
@KomodoDave, 이것은 메서드 범위에서도 잘못 되었기 때문입니다. getName자식 클래스에서 호출 하면 자식 클래스 이름이 출력됩니다. 그런 다음 작업중인 수업을 정말로 원하면 까다로워집니다.
Kenet Jervet 2015 년

@KenetJervet 부모 클래스 getName에서 호출 하면 자식 클래스 이름이 출력 된다는 의미 입니까? 그것을 지적 해 주셔서 감사합니다.
KomodoDave 2015 년

5
OO 용어에서 솔루션 ( getName()메서드가 수퍼 클래스에 정의 된 경우에도 실제 런타임 자식 클래스 이름을 반환 )은 정확합니다.
sxc731

22

클래스 본문 내에서 클래스 이름이 아직 정의되지 않았으므로 사용할 수 없습니다. 단순히 수업 이름을 입력 할 수 없습니까? 해결책을 찾을 수 있도록 문제에 대해 더 많이 말해야 할 수도 있습니다.

이 작업을 수행하기 위해 메타 클래스를 만들 것입니다. 클래스 생성시 (개념적으로 class : block의 맨 끝에서) 호출되며 생성되는 클래스를 조작 할 수 있습니다. 나는 이것을 테스트하지 않았습니다.

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'

내가하려는 작업을 명확히하기 위해 메서드 외부 에서 클래스 변수 'input'을 만들고 초기화해야합니다 . 나는 여러 개의 작은 클래스를 가지고 있는데, 각각의 클래스 이름을 매개 변수로 사용하여 'get_input'을 호출해야합니다. 나는 이것을 일반화하려고 노력하고 있으므로 각 수업 (100 개 정도)에 가서 수업 이름을 입력 할 필요가 없습니다.
Jonathan Ginsburg

좋아, 도움이 될 메타 클래스로 내 대답을 업데이트했습니다.
Ned Batchelder

1
어떻게합니까 MyTypesuperInputAssigningMetaclass을 참조하십시오?
A.Wan

16

클래스의 개인 속성으로 액세스 할 수 있습니다.

cls_name = self.__class__.__name__

편집하다:

에서 말했듯 Ned Batcheler이 이것은 클래스 본문에서는 작동하지 않지만 메서드에서는 작동합니다.


11

PEP 3155가 도입 __qualname__되었으며 Python 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'

그러나 나는 이것을하지 않을 것이다. 내 원래 대답은 여전히 ​​내가 선호하는 솔루션입니다. 원래 답변 :

아마도 가장 간단한 해결책은 데코레이터를 사용하는 것입니다. 이것은 메타 클래스를 포함하는 Ned의 대답과 비슷하지만 덜 강력합니다 (데코레이터는 흑 마법을 할 수 있지만 메타 클래스는 고대의 오컬트 흑 마법을 할 수 있습니다 ).

>>> 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__)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.