2017-01-02 10 views
-4
class UpperAttrMetaclass(type): 

    var = "test" 

    def __new__(upperattr_metaclass, future_class_name, 
       future_class_parents, future_class_attr): 
     print("hello world") 
     uppercase_attr = {} 
     for name, val in future_class_attr.items(): 
      if not name.startswith('__'): 
       uppercase_attr[name.upper()] = val 
      else: 
       uppercase_attr[name] = val 

     # reuse the type.__new__ method 
     # this is basic OOP, nothing magic in there 
     return type.__new__(upperattr_metaclass, future_class_name, 
          future_class_parents, uppercase_attr) 


class Hello(object): 

    __metaclass__ = UpperAttrMetaclass 

    bar = "test" 

obj = Hello() 
print(obj.BAR) # obj has no attribute named BAR 

TraceBack (самый последний вызов последнего):
файла "E: \ питон \ test.py", строка 32, в
печати (obj.BAR)
AttributeError: ' Hello 'объект не имеет атрибута' BAR 'Некоторые вопросы о Python3 метакласса

Почему метакласс UpperAttrMetaclass не работает?

+1

Возможный дубликат [Python3 Singleton метод метаклассом не работает] (http://stackoverflow.com/questions/17237857/python3-singleton-metaclass-method-not-working) – vaultah

+0

Почему так downvoted этот вопрос ? Он имеет идеальный пример кода и хорошо сформулированный вопрос (если он зависит от названия вопроса). – jsbueno

ответ

1

В Python3 способ указать метакласс изменился с Python2 несовместимым образом.

Начиная с Python 3.0, способ указать метакласс - использовать имя метакласса, как если бы это был параметр Named в самом объявлении class.

Таким образом, в приведенном выше примере, вы shuld объявить класс Hello как:

class Hello(metaclass=UpperAttrMetaclass): 
    bar = "test" 

Проверьте документацию по адресу: https://docs.python.org/3.0/whatsnew/3.0.html#changed-syntax

Кроме того, как вы отметили, поставив атрибут __metaclass__ в ac alss body не является ошибкой, но ничего вообще, но объявляет атрибут с этим именем.

После нескольких выпусков версий Python3.x это единственное синтаксическое изменение, которое несовместимо с Python 2 и не может быть обходным путем простым способом, так что код является как Python 2.x, так и Python Совместимость 3.x в одно и то же время.

Если вам нужна такая же база кода для запуска на Python 2 и Python 3, пакет с именем six вызывает вызов with_metaclass, который строит базу динамического класса с синтаксисом, совместимым с обеими версиями. (https://pythonhosted.org/six/#syntax-compatibility)

 Смежные вопросы

  • Нет связанных вопросов^_^