Проверьте, был ли атрибут класса определен или получен в данном классе - PullRequest
1 голос
/ 10 марта 2011

Пример

class A:
    foo = 1

class B:
    foo = 2

class C:
    foo = 3

class D(A, B, C):
    pass

def collect_foo(cls):
    import inspect
    foos = []
    for c in inspect.getmro(cls):
        if hasattr(c, 'foo'):
            foos.append(c.foo)
    return foos

Теперь collect_foo(D) возвращает [1, 1, 2, 3] - 1 удваивается, поскольку D выводит его из A. Вопрос - как получить уникальные foo с. Первое, что мне пришло в голову, это проверка, является ли свойство производным или объявленным в данном классе - возможно ли это? Как это сделать?

Ответы [ 4 ]

8 голосов
/ 10 марта 2011

Просто отметьте

'foo' in c.__dict__

вместо

hasattr(c, 'foo')

Это даст только True, если атрибут определен в c.

6 голосов
/ 10 марта 2011

Я полагаю, что это сработает ... Посмотрите, находится ли он в атрибуте __dict__ класса.Но убедитесь, что вы действительно хотите сделать это в первую очередь.

Пример:

if name in cls.__dict__:
    # ... your code here ...
    pass
1 голос
/ 10 марта 2011

"Дело в том, что есть некоторые атрибуты, которые я не хочу переопределять, но смешивать и использовать для производного класса"

Это именно то, что делает искажение пространства имен в Python.Атрибуты, которые не должны быть переопределены, должны начинаться с двух подчеркиваний.Таким образом, они не переопределяются, но остаются уникальными для каждого класса.

0 голосов
/ 07 декабря 2017

Я согласен с принятым ответом, но @classmethod не соответствует моему случаю ...

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

т.е. (в Python 3.6):
if method_name in self.__class__.__dict__.keys(): # do something

Я объяснил это следующим образом.

  1. self это экземпляр
  2. __class__ фактический тип этого экземпляра
  3. , следовательно, dict содержит только методы, фактически переопределенные в производном классе.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...