IC # ми робимо це через рефлексію. У Javascript це просто так:
for(var propertyName in objectName)
var currentPropertyValue = objectName[propertyName];
Як це зробити в Python?
@property.
IC # ми робимо це через рефлексію. У Javascript це просто так:
for(var propertyName in objectName)
var currentPropertyValue = objectName[propertyName];
Як це зробити в Python?
@property.
Відповіді:
for property, value in vars(theObject).iteritems():
print property, ": ", value
Майте на увазі, що в деяких рідкісних випадках є __slots__властивість, таких класів часто немає __dict__.
__setattr__(). Встановлення значень безпосередньо у словнику обходить установку об'єкта (та / або його батьків). У python досить часто зустрічається, що більше речей, ніж очі, відбувається у фоновому режимі під час налаштування атрибутів (наприклад, санітарія), використовуючи setattr()гарантування того, що ви не пропустите або змушені самі явно їх обробляти.
vars()повертає лише статичні члени (тобто атрибути об'єктів та методи, зареєстровані разом з об'єктами __dict__). Він не повертає динамічних членів (тобто атрибутів об'єктів та методів, динамічно визначених методом цього об'єкта __getattr__()чи подібною магією). Ймовірно, ваше бажане file.ImplementationNameвластивість визначається динамічно і, отже, не доступне для vars()або dir().
Див inspect.getmembers(object[, predicate]).
Повернути всі члени об'єкта у списку (ім'я, значення) пар, відсортованих за іменем. Якщо надається необов'язковий аргумент предиката, включаються лише члени, для яких предикат повертає справжнє значення.
>>> [name for name,thing in inspect.getmembers([])]
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
'__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__',
'__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__','__reduce_ex__',
'__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__',
'__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index',
'insert', 'pop', 'remove', 'reverse', 'sort']
>>>
attributesзамість members(чи є різниця між ними?). Вони могли зафіксувати ім’я в Python 3.0, щоб зробити його послідовним.
__dict__, вибачте.
inspect.getmembers()обгортає dir()з (переважно незначними) побічними перевагами (A), включаючи атрибути динамічного класу та атрибути метакласу та (B), виключаючи членів, що не відповідають пройденому предикату. Позіхання, правда? inspect.getmembers()підходить для сторонніх бібліотек, що підтримують усі можливі типи об'єктів. Для стандартних випадків використання, однак, dir()абсолютно достатньо.
dir()це простий спосіб. Дивіться тут:
dir()дякувати.
__dict__Властивість об'єкта представляє собою словник усіх інших його певних властивостей. Зауважте, що класи Python можуть змінювати getattr
і створювати речі, схожі на властивості, але не входять __dict__. Там також функції BUILTIN vars()і dir()які відрізняються тонкими способами. І __slots__може замінити __dict__в деяких незвичних заняттях.
Об'єкти складні в Python. __dict__є правильним місцем для початку програмування у стилі рефлексії. dir()це місце для початку, якщо ви злому в інтерактивній оболонці.
print vars.__doc__що вказує на те, With an argument, equivalent to object.__dict__якими були б найтонші відмінності?
georg scholly коротша версія
print vars(theObject)
Якщо ви шукаєте відображення всіх властивостей, відповіді вище чудові.
Якщо ви просто хочете отримати ключі словника (який відрізняється від 'об’єкта' в Python), використовуйте
my_dict.keys()
my_dict = {'abc': {}, 'def': 12, 'ghi': 'string' }
my_dict.keys()
> ['abc', 'def', 'ghi']
obj['key']проти obj.property), і питання стосується властивостей об'єкта. Я даю тут свою відповідь, тому що між ними існує легка плутанина.
Це повністю висвітлено в інших відповідях, але я зроблю це чітко. Об'єкт може мати атрибути класу та статичні та динамічні атрибути екземпляра.
class foo:
classy = 1
@property
def dyno(self):
return 1
def __init__(self):
self.stasis = 2
def fx(self):
return 3
stasisє статичним, dynoє динамічним (пор. декоратор властивостей) і classyє атрибутом класу. Якщо ми просто зробимо __dict__або varsотримаємо лише статичний.
o = foo()
print(o.__dict__) #{'stasis': 2}
print(vars(o)) #{'stasis': 2}
Тож якщо ми хочемо, щоб інші __dict__отримали все (і більше). Сюди входять магічні методи та атрибути та звичайні зв'язані методи. Тож давайте уникати таких:
d = {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
print(d) #{'stasis': 2, 'classy': 1, 'dyno': 1}
typeВикликається метод власності оформлений (динамічний атрибут) дасть вам тип значення, а НЕ method. Щоб довести це, давайте json впорядкує це:
import json
print(json.dumps(d)) #{"stasis": 2, "classy": 1, "dyno": 1}
Якби це був метод, він би зазнав краху.
TL; DR. спробуйте закликати extravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}всіх трьох, але не методами чи магією.