IC # kita melakukannya melalui refleksi. Dalam Javascript itu sederhana seperti:
for(var propertyName in objectName)
var currentPropertyValue = objectName[propertyName];
Bagaimana cara melakukannya dengan Python?
@property
.
IC # kita melakukannya melalui refleksi. Dalam Javascript itu sederhana seperti:
for(var propertyName in objectName)
var currentPropertyValue = objectName[propertyName];
Bagaimana cara melakukannya dengan Python?
@property
.
Jawaban:
for property, value in vars(theObject).iteritems():
print property, ": ", value
Ketahuilah bahwa dalam beberapa kasus yang jarang ada __slots__
properti, kelas seperti itu seringkali tidak memiliki __dict__
.
__setattr__()
. Menetapkan nilai secara langsung pada kamus melewati penyetel objek (dan / atau orang tuanya). Ini cukup umum dalam python bahwa lebih banyak hal daripada bertemu mata terjadi di latar belakang selama pengaturan atribut (misalnya sanitasi), menggunakan setattr()
memastikan bahwa Anda tidak ketinggalan, atau dipaksa untuk menanganinya secara eksplisit sendiri.
vars()
hanya mengembalikan anggota statis (yaitu, atribut objek dan metode yang terdaftar dengan objek itu __dict__
). Itu tidak mengembalikan anggota dinamis (yaitu, atribut dan metode objek didefinisikan secara dinamis oleh __getattr__()
metode objek itu atau sihir yang serupa). Kemungkinan besar, file.ImplementationName
properti yang Anda inginkan didefinisikan secara dinamis dan karenanya tidak tersedia untuk vars()
atau dir()
.
Lihat inspect.getmembers(object[, predicate])
.
Kembalikan semua anggota suatu objek dalam daftar pasangan (nama, nilai) yang diurutkan berdasarkan nama. Jika argumen predikat opsional disediakan, hanya anggota yang predikatnya mengembalikan nilai sebenarnya yang disertakan.
>>> [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
alih-alih members
(apakah ada perbedaan di antara keduanya?). Mereka bisa memperbaiki nama dengan Python 3.0 agar konsisten.
__dict__
, maaf.
inspect.getmembers()
membungkus dir()
dengan manfaat samping (sebagian besar diabaikan) (A) termasuk atribut kelas dinamis dan atribut metaclass dan (B) tidak termasuk anggota yang tidak cocok dengan predikat yang lulus. Menguap, kan? inspect.getmembers()
sesuai untuk pustaka pihak ketiga yang secara umum mendukung semua jenis objek yang mungkin. Namun, untuk kasus penggunaan standar, dir()
cukup memadai.
dir()
adalah cara sederhana. Lihat disini:
dir()
terima kasih.
The __dict__
properti dari objek adalah kamus semua properti lainnya yang ditetapkan. Perhatikan bahwa kelas Python dapat mengesampingkan getattr
dan membuat hal-hal yang terlihat seperti properti tetapi tidak ada di dalamnya__dict__
. Ada juga fungsi builtin vars()
dan dir()
yang berbeda dalam cara yang halus. Dan __slots__
dapat menggantikan __dict__
di beberapa kelas yang tidak biasa.
Objek rumit dengan Python. __dict__
adalah tempat yang tepat untuk memulai pemrograman gaya refleksi. dir()
adalah tempat untuk memulai jika Anda mencari-cari di shell interaktif.
print vars.__doc__
menunjukkan bahwa With an argument, equivalent to object.__dict__
Jadi apa perbedaan yang halus itu?
georg versi yang lebih pendek
print vars(theObject)
Jika Anda mencari refleksi dari semua properti, jawaban di atas sangat bagus.
Jika Anda hanya mencari untuk mendapatkan kunci kamus (yang berbeda dari 'objek' dengan Python), gunakan
my_dict.keys()
my_dict = {'abc': {}, 'def': 12, 'ghi': 'string' }
my_dict.keys()
> ['abc', 'def', 'ghi']
obj['key']
vs. obj.property
) dan pertanyaannya adalah tentang properti objek. Saya meletakkan jawaban saya di sini karena ada kebingungan yang mudah antara keduanya.
Ini sepenuhnya tercakup oleh jawaban lain, tetapi saya akan membuatnya eksplisit. Objek mungkin memiliki atribut kelas dan atribut instance statis dan dinamis.
class foo:
classy = 1
@property
def dyno(self):
return 1
def __init__(self):
self.stasis = 2
def fx(self):
return 3
stasis
bersifat statis, dyno
dinamis (lih. dekorator properti) dan classy
merupakan atribut kelas. Jika kita hanya melakukan __dict__
atau vars
kita hanya akan mendapatkan yang statis.
o = foo()
print(o.__dict__) #{'stasis': 2}
print(vars(o)) #{'stasis': 2}
Jadi jika kita mau yang lain __dict__
akan mendapatkan segalanya (dan banyak lagi). Ini termasuk metode dan atribut sihir dan metode terikat normal. Jadi mari kita hindari itu:
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}
Yang type
dipanggil dengan metode yang didekorasi dengan properti (atribut dinamis) akan memberi Anda jenis nilai yang dikembalikan, bukan method
. Untuk membuktikan ini, mari kita rekatkan:
import json
print(json.dumps(d)) #{"stasis": 2, "classy": 1, "dyno": 1}
Seandainya itu metode yang pasti akan crash.
TL; DR. coba panggil extravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
ketiganya, tetapi jangan metode atau sihir.