IC # chúng tôi làm điều đó thông qua sự phản ánh. Trong Javascript, nó đơn giản như:
for(var propertyName in objectName)
var currentPropertyValue = objectName[propertyName];
Làm thế nào để làm điều đó trong Python?
@property
.
IC # chúng tôi làm điều đó thông qua sự phản ánh. Trong Javascript, nó đơn giản như:
for(var propertyName in objectName)
var currentPropertyValue = objectName[propertyName];
Làm thế nào để làm điều đó trong Python?
@property
.
Câu trả lời:
for property, value in vars(theObject).iteritems():
print property, ": ", value
Xin lưu ý rằng trong một số trường hợp hiếm hoi có một __slots__
tài sản, các lớp như vậy thường không có __dict__
.
__setattr__()
. Đặt giá trị trực tiếp trên từ điển bỏ qua bộ setter của đối tượng (và / hoặc cha mẹ của nó). Điều khá phổ biến ở python là nhiều thứ hơn mắt thường xảy ra trong nền trong khi cài đặt thuộc tính (ví dụ như vệ sinh), sử dụng setattr()
đảm bảo rằng bạn không bỏ lỡ hoặc buộc phải tự xử lý chúng một cách rõ ràng.
vars()
chỉ trả về các thành viên tĩnh (nghĩa là các thuộc tính và phương thức đối tượng đã đăng ký với đối tượng đó __dict__
). Nó không trả về các thành viên động (nghĩa là các thuộc tính và phương thức đối tượng được xác định động bởi __getattr__()
phương thức của đối tượng đó hoặc phép thuật tương tự). Trong tất cả khả năng, file.ImplementationName
tài sản mong muốn của bạn được xác định động và do đó không có sẵn cho vars()
hoặc dir()
.
Xem inspect.getmembers(object[, predicate])
.
Trả về tất cả các thành viên của một đối tượng trong danh sách các cặp (tên, giá trị) được sắp xếp theo tên. Nếu đối số vị từ tùy chọn được cung cấp, chỉ các thành viên mà vị từ trả về giá trị thực mới được đưa vào.
>>> [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
thay vì members
(có sự khác biệt nào giữa hai tài liệu này không?). Họ có thể đã sửa tên trong Python 3.0 để làm cho nó phù hợp.
__dict__
, xin lỗi.
inspect.getmembers()
kết dir()
hợp với các lợi ích phụ (hầu hết không đáng kể) của (A) bao gồm các thuộc tính lớp động và thuộc tính siêu dữ liệu và (B) không bao gồm các thành viên không khớp với vị từ đã qua. Ngáp phải không? inspect.getmembers()
là thích hợp cho các thư viện bên thứ ba hỗ trợ chung cho tất cả các loại đối tượng có thể. Đối với các trường hợp sử dụng tiêu chuẩn, tuy nhiên, dir()
hoàn toàn đủ.
dir()
là cách đơn giản. Xem tại đây:
dir()
cảm ơn bạn.
Các __dict__
tài sản của đối tượng là một cuốn từ điển của tất cả các thuộc tính được định nghĩa khác của nó. Lưu ý rằng các lớp Python có thể ghi đè getattr
và tạo ra những thứ trông giống như các thuộc tính nhưng không có trong đó __dict__
. Ngoài ra còn có các hàm dựng sẵn vars()
và dir()
khác nhau theo những cách tinh tế. Và __slots__
có thể thay thế __dict__
trong một số lớp học bất thường.
Các đối tượng rất phức tạp trong Python. __dict__
là nơi thích hợp để bắt đầu lập trình kiểu phản chiếu. dir()
là nơi để bắt đầu nếu bạn hack xung quanh trong một vỏ tương tác.
print vars.__doc__
chỉ ra rằng With an argument, equivalent to object.__dict__
sự khác biệt tinh tế sẽ là gì?
georg scholly phiên bản ngắn hơn
print vars(theObject)
Nếu bạn đang tìm kiếm sự phản ánh của tất cả các thuộc tính, câu trả lời ở trên là tuyệt vời.
Nếu bạn chỉ đơn giản là tìm kiếm các khóa của từ điển (khác với 'đối tượng' trong Python), hãy sử dụng
my_dict.keys()
my_dict = {'abc': {}, 'def': 12, 'ghi': 'string' }
my_dict.keys()
> ['abc', 'def', 'ghi']
obj['key']
so với obj.property
) và câu hỏi là về các thuộc tính đối tượng. Tôi đặt câu trả lời của mình ở đây vì có sự nhầm lẫn dễ dàng giữa hai người.
Điều này hoàn toàn được bao phủ bởi các câu trả lời khác, nhưng tôi sẽ làm cho nó rõ ràng. Một đối tượng có thể có các thuộc tính lớp và thuộc tính thể hiện tĩnh và động.
class foo:
classy = 1
@property
def dyno(self):
return 1
def __init__(self):
self.stasis = 2
def fx(self):
return 3
stasis
là tĩnh, dyno
là động (xem trang trí classy
thuộc tính ) và là một thuộc tính lớp. Nếu chúng ta chỉ đơn giản làm __dict__
hoặc vars
chúng ta sẽ chỉ có được một tĩnh.
o = foo()
print(o.__dict__) #{'stasis': 2}
print(vars(o)) #{'stasis': 2}
Vì vậy, nếu chúng ta muốn những người khác __dict__
sẽ nhận được mọi thứ (và nhiều hơn nữa). Điều này bao gồm các phương thức và thuộc tính ma thuật và các phương thức ràng buộc thông thường. Vì vậy, hãy tránh những điều đó:
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}
Cuộc type
gọi với một phương thức trang trí thuộc tính (một thuộc tính động) sẽ cung cấp cho bạn loại giá trị được trả về, không method
. Để chứng minh điều này, hãy json xâu chuỗi nó:
import json
print(json.dumps(d)) #{"stasis": 2, "classy": 1, "dyno": 1}
Nếu nó là một phương pháp thì nó sẽ bị sập.
TL; DR. hãy thử gọi extravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
cho cả ba, nhưng không phải phương pháp cũng không phải phép thuật.