Python: ссылка на класс из строки?

1

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

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 ответа

5
Лучший ответ

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

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

class X(object): pass

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

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

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

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

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

print self.var

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

  • 0
    +1 приятно объяснил
  • 0
    хммм: "переменная 'X' будет ссылкой" не точно. Идентификатор «X» является самим объектом класса и может использоваться везде, где будет использоваться константа.
Показать ещё 1 комментарий
2

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

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

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

  • 0
    Ха-ха, имеет смысл! Большое спасибо.
  • 0
    По-видимому, нет, почему он спрашивает, знает ли он ответ?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню