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'}
всіх трьох, але не методами чи магією.