Страницы

Поиск по вопросам

понедельник, 6 января 2020 г.

Метаклассы | Python

#python #python_3x #metaclass


Есть следующий код:

def upper_attr(class_name, class_parents, class_attrs):
    attr = dict((key.upper(), value) for key, value in class_attrs.items() if not
key.startswith('__'))
    return type(class_name, class_parents, attr)
class My(object):
    __metaclass__ = upper_attr
    var = 'hello world'
obj = My()
print(hasattr(obj, 'var'))


Ожидаю получить False, так как __metaclass__ переводит названия всех атрибутов в
верхний регистр, но получаю True, где я ошибся? 

Но если сделать так:

class My(metaclass=upper_attr):
    ...


То все работает, почему же не работает с __metaclass__ не имею понятия.
    


Ответы

Ответ 1



Код для python3: class MetaClass(type): def __call__(self, *args, **kwargs): obj = type.__call__(self, *args, **kwargs) for key, value in list(obj.__dict__.items()): if (key[0] == '_') and (key[-1] == '_'): continue else: obj.__dict__[key.upper()] = value del obj.__dict__[key] return obj class My(object, metaclass=MetaClass): def __init__(self): self.var = 'hello world' obj = My() print(obj.__dict__) print(hasattr(obj, 'var'))

Ответ 2



Скорее всего, вы используете Python 3, а не Python 2. В Python 3 поменялся синтаксис и теперь вместо __metaclass__ следует писать так: class My(metaclass=upper_attr): var = 'hello world'

Ответ 3



Вот нашёл идентичный вашему код сдесь всё правильно надеюсь он поможет вам найти ошибку def upper_attr(future_class_name, future_class_parents, future_class_attr): # берем любой атрибут, не начинающийся с '__' attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__')) # переводим их в верхний регистр uppercase_attr = dict((name.upper(), value) for name, value in attrs) # создаем класс с помощью 'type' return type(future_class_name, future_class_parents, uppercase_attr) class Foo(object): __metaclass__ = upper_attr bar = 'bip' print (hasattr(Foo, 'bar')) "False" print (hasattr(Foo, 'BAR')) "True" """ f = Foo() print (f.BAR) "bip" """

Комментариев нет:

Отправить комментарий