Итерация по «общедоступным» атрибутам объекта

Недавно я обнаружил, что пишу код следующим образом:

 для имени в каталоге (объект):
     если name.startswith ('__'): продолжить
     ...

Есть ли более питонический способ доступа к «общедоступному» пространству имен объекта?

Вы можете подготовить список «общедоступных» атрибутов (как список или генератор) до:

 >>> public_props = (name for name in dir(object) if not name.startswith('_')) >>> for name in public_props: print name 

Но, пожалуйста, прочитайте примечание о функции dir() в документации:

Примечание. Поскольку dir() поставляется в основном как удобство для использования в интерактивном приглашении, он пытается предоставить интересный набор имен больше, чем пытается предоставить строго или последовательно определенный набор имен, а его подробное поведение может измениться в разных версиях , Например, атрибуты metaclass не входят в список результатов, когда аргумент является классом.

Вы также должны знать, что любой класс может реализовать __dir__() который может возвращать список имен, которые не обязательно соответствуют именам атрибутов. Другими словами, dir(something) не гарантирует, что результат вернет атрибуты something .

vars этого вы можете использовать функцию vars .

Например:

 >>> class C(object): ... def __init__(self): ... self.__foo = 'foo' ... >>> c = C() >>> dir(c) ['_C__foo', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] >>> vars(c) {'_C__foo': 'foo'} 

Обратите внимание, что, как отметил Никлас Р, переменные с одним символом подчеркивания также считаются частными. Однако vars() имеет то преимущество, что исключает все переменные экземпляра.

Я чувствую, что итерация над пониманием списка немного более питонична, чем использование ключевого слова continue , но это может быть просто вопросом вкуса. Это, по общему признанию, не намного элегантнее, чем у вас уже есть.

 for attr in (a for a in dir(object) if not a.startswith('_')): pass 

Примечание. Отдельные атрибуты подчеркивания также не являются «общедоступными».