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)รวมทั้งคุณลักษณะระดับแบบไดนามิกและคุณลักษณะ metaclassและ(ข)ไม่รวมสมาชิกไม่ตรงกับคำกริยาผ่าน หาวใช่ไหม? inspect.getmembers()
เหมาะสำหรับไลบรารีของบุคคลที่สามโดยทั่วไปที่สนับสนุนประเภทอ็อบเจ็กต์ที่เป็นไปได้ทั้งหมด อย่างไรก็ตามสำหรับกรณีการใช้งานมาตรฐานก็dir()
เพียงพอแล้ว
dir()
เป็นวิธีง่ายๆ ดูที่นี่:
dir()
ขอบคุณ
__dict__
คุณสมบัติของวัตถุที่เป็นพจนานุกรมของคุณสมบัติอื่น ๆ ทั้งหมดที่กำหนดไว้ โปรดทราบว่าการเรียนหลามสามารถแทนที่getattr
และทำให้สิ่งที่มีลักษณะเหมือนคุณสมบัติ __dict__
แต่ไม่ได้อยู่ใน นอกจากนี้ยังมีฟังก์ชั่นในตัวvars()
และdir()
ที่มีความแตกต่างกันในรูปแบบที่ลึกซึ้ง และ__slots__
สามารถแทนที่__dict__
ในคลาสที่ผิดปกติบางอย่าง
วัตถุมีความซับซ้อนใน Python __dict__
เป็นจุดเริ่มต้นที่เหมาะสมสำหรับการเขียนโปรแกรมแบบสะท้อนแสง dir()
เป็นจุดเริ่มต้นหากคุณกำลังแฮ็กข้อมูลในเชลล์แบบโต้ตอบ
print vars.__doc__
บ่งชี้ว่าWith an argument, equivalent to object.__dict__
แล้วความแตกต่างที่ลึกซึ้งจะเป็นอย่างไร?
georg scholly short version
print vars(theObject)
หากคุณกำลังมองหาการสะท้อนของคุณสมบัติทั้งหมดคำตอบข้างต้นนั้นดีมาก
หากคุณต้องการรับคีย์ของพจนานุกรม (ซึ่งแตกต่างจาก 'object' ใน 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
เป็นไดนามิก (ตัวตกแต่งคุณสมบัติ cf. ) และ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'}
ทั้งสาม แต่ไม่ใช่วิธีการหรือเวทมนตร์