Python: ссылка на класс из строки? - PullRequest
1 голос
/ 09 апреля 2009

Как использовать строку, содержащую имя класса, для ссылки на сам класс?
Смотрите этот (не работает) пример ...

class WrapperClass:
    def display_var(self):
        #FIXME: self.__class_name__.__name__ is a string
        print self.__class__.__name__.the_var

class SomeSubClass(WrapperClass):
    var = "abc"

class AnotherSubClass(WrapperClass):
    var = "def"

И очевидное сообщение об ошибке:

>>> b = SomeSubClass()
>>> b.display_var()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 4, in display_var
AttributeError: 'str' object has no attribute 'the_var'
>>> 

Спасибо!

Ответы [ 3 ]

7 голосов
/ 09 апреля 2009

Как использовать строку, содержащую имя класса, для ссылки на сам класс?

Классы не особенные, это просто значения, содержащиеся в переменных. Если вы сказали:

class X(object): pass

в глобальной области видимости, тогда переменная "X" будет ссылкой на объект класса.

Вы можете получить глобальные переменные текущего скрипта / модуля в виде словаря, используя b globals () ’, так что:

classobj= globals()[self.__class__.__name__]
print classobj.var

(locals() также доступен для локальных переменных; между ними вам не нужно использовать ужасный eval() для доступа к переменным.)

Однако, как отмечает Дэвид, self.__class__ уже уже classobj, поэтому нет необходимости бегать по извлечению из глобальных переменных по имени; self.__class__.var в порядке. Хотя на самом деле:

print self.var

будет обычным простым способом сделать это. Члены класса доступны как члены их экземпляров, если экземпляр не перезаписывает имя чем-то другим.

2 голосов
/ 09 апреля 2009

В зависимости от того, где вы получаете эту строку, любой общий метод может быть небезопасным (один из таких методов - просто использовать eval(string). Лучший способ - определить имена, определяющие dict для классов:

class WrapperClass:
    def display_var(self):
        #FIXME: self.__class_name__.__name__ is a string
        print d[self.__class__.__name__].the_var

class SomeSubClass(WrapperClass):
    the_var = "abc"

class AnotherSubClass(WrapperClass):
    the_var = "def"

d = {'WrapperClass': WrapperClass, 'SomeSubClass': SomeSubClass, 'AnotherSubClass': AnotherSubClass}
AnotherSubClass().display_var()
# prints 'def'
1 голос
/ 09 апреля 2009

Ваш пример сработает, если вы позвоните print self.__class__.var. Я не думаю, что нужно использовать имя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...