В последнее время я нахожу, что пишу код следующим образом:
for name in dir( object ): if name.startswith( '__' ) : continue ...
Есть ли более питонический способ доступа к объекту "общедоступное" пространство имен?
В последнее время я нахожу, что пишу код следующим образом:
for name in dir( object ): if name.startswith( '__' ) : continue ...
Есть ли более питонический способ доступа к объекту "общедоступное" пространство имен?
Вы можете подготовить список "общедоступных" атрибутов (как список или генератор) до:
>>> 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
функцию.
Например:
>>> 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
Примечание. Отдельные атрибуты подчеркивания также не являются "общедоступными".