การแก้ไข __dict__ ของวัตถุเพื่อกำหนดคุณสมบัติให้ถือว่าเป็น Pythonic หรือไม่?


12

ฉันมีคลาสที่ขยายวัตถุจากแถวที่พบในฐานข้อมูล (หรือแหล่งอื่นเช่น MongoDB ไฟล์ CSV เป็นต้น) ในการตั้งค่าคุณสมบัติของวัตถุมันไม่สิ่งที่ต้องการหรือself.__dict__.update(**properties)obj.__dict__.update(**properties)

สิ่งนี้ถือว่าเป็น Pythonic หรือไม่ นี่เป็นรูปแบบที่ดีที่ฉันควรใช้ต่อไปหรือว่านี่เป็นรูปแบบที่แย่หรือไม่?


1
ฉันไม่รู้ว่ามันเป็น Pythonic หรือเปล่า แต่มันเป็นเรื่องธรรมดาที่จะทำใน dunder init
user16764

คำตอบ:


10

ใน Python 3.3 จะมีการเพิ่มประเภทใหม่types.SimpleNamespace()และในเอกสารอธิบายดังกล่าว:

ประเภทนี้เทียบเท่ากับรหัสต่อไปนี้:

class SimpleNamespace:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
    def __repr__(self):
        keys = sorted(self.__dict__)
        items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
        return "{}({})".format(type(self).__name__, ", ".join(items))

หมายเหตุ__init__วิธีการของชนิดนั้น คุณไม่สามารถรับรองเทคนิคที่ดีกว่าเอกสาร Python


แม้ว่าSimpleNamespaceจะค่อนข้างแตกต่างจากประเภทส่วนใหญ่ที่ไม่มีชุดคุณลักษณะคงที่

7
ถ้าพูดถึงเอกสาร Python จากdocs.python.org/2/library/stdtypes.html "แอตทริบิวต์พิเศษของทุกโมดูลคือ__dict__นี่คือพจนานุกรมที่บรรจุตารางสัญลักษณ์ของโมดูลการแก้ไขพจนานุกรมนี้จะเปลี่ยนสัญลักษณ์ของโมดูล ตาราง แต่ไม่สามารถกำหนดค่าโดยตรงให้กับ__dict__แอตทริบิวต์ (คุณสามารถเขียนm.__dict__['a'] = 1ซึ่งกำหนดm.aเป็น 1 แต่คุณทำไม่ได้writem.__dict__ = {}) ไม่แนะนำให้แก้ไข__dict__โดยตรง "ซึ่งเป็นสิ่งแรกที่กระตุ้นให้ฉันถามคำถามนี้
skyler

@skyler: ทราบว่าที่กล่าวถึงเพียงnamespace โมดูล globals()ฟังก์ชันส่งกลับ namespace เดียวกันและมีวิธีการที่มักจะดีกว่าที่จะแก้ปัญหาที่เกิดขึ้นกว่าการตั้งค่าแบบไดนามิก Globals จึงเตือน
Martijn Pieters
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.