ในภาษา OO ที่รู้จักกันดีที่สุดนิพจน์เช่นSomeClass(arg1, arg2)
นั้นจะจัดสรรอินสแตนซ์ใหม่เริ่มต้นแอตทริบิวต์ของอินสแตนซ์แล้วส่งคืน
ในภาษา OO ที่รู้จักกันดีส่วน "initialise the instance" สามารถปรับแต่งได้สำหรับแต่ละคลาสโดยการกำหนดConstructorซึ่งโดยพื้นฐานแล้วจะเป็นเพียงกลุ่มของรหัสที่ทำงานกับอินสแตนซ์ใหม่ ) เพื่อตั้งค่าเงื่อนไขเริ่มต้นที่ต้องการ ในหลามสอดคล้องนี้ในชั้นเรียน__init__
วิธีการ
Python __new__
ไม่มีอะไรมากและไม่มีอะไรที่น้อยไปกว่าการปรับแต่งแบบต่อคลาสคล้ายกันของส่วน "จัดสรรอินสแตนซ์ใหม่" หลักสูตรนี้ช่วยให้คุณสามารถทำสิ่งผิดปกติเช่นคืนอินสแตนซ์ที่มีอยู่แทนที่การจัดสรรอินสแตนซ์ใหม่ ดังนั้นใน Python เราไม่ควรนึกถึงส่วนนี้เกี่ยวกับการจัดสรร สิ่งที่เราต้องการคือสิ่งที่__new__
เกิดขึ้นพร้อมกับตัวอย่างที่เหมาะสมจากที่อื่น
แต่ก็ยังมีเพียงครึ่งหนึ่งของงานและไม่มีทางที่ระบบ Python จะรู้ว่าบางครั้งคุณต้องการที่จะทำงานอีกครึ่งหนึ่งของงาน ( __init__
) หลังจากนั้นและบางครั้งคุณก็ทำไม่ได้ หากคุณต้องการพฤติกรรมดังกล่าวคุณต้องพูดอย่างชัดเจน
บ่อยครั้งที่คุณสามารถ refactor เพื่อให้คุณต้องการเท่านั้น__new__
หรือดังนั้นคุณไม่ต้องการ__new__
หรือเพื่อที่__init__
จะทำงานแตกต่างกันในวัตถุที่เริ่มต้นแล้ว แต่ถ้าคุณอยากจะหลามจะช่วยให้คุณจริงจะกำหนด "งาน" เพื่อให้SomeClass(arg1, arg2)
ไม่จำเป็นต้องโทรตามมาด้วย__new__
__init__
ในการทำเช่นนี้คุณต้องสร้างเมตาคลาสและกำหนด__call__
วิธีการ
metaclass เป็นเพียงคลาสของคลาส และ__call__
เมธอดclass ' จะควบคุมสิ่งที่เกิดขึ้นเมื่อคุณเรียกใช้อินสแตนซ์ของคลาส ดังนั้นmetaclass ' __call__
วิธีการควบคุมสิ่งที่เกิดขึ้นเมื่อคุณเรียกชั้นเรียน; คือมันช่วยให้คุณสามารถredefine กลไกเช่นการสร้างตั้งแต่ต้นจนจบ นี่คือระดับที่คุณสามารถใช้กระบวนการสร้างอินสแตนซ์ที่ไม่ได้มาตรฐานอย่างสมบูรณ์ที่สุดเช่นรูปแบบซิงเกิล ในความเป็นจริงมีน้อยกว่า 10 บรรทัดของรหัสคุณสามารถใช้Singleton
metaclass ที่ไม่ต้องการให้คุณ futz ด้วย__new__
เลยและสามารถเปลี่ยนชั้นเรียนปกติอื่นๆให้กลายเป็นซิงเกิลเพียงแค่เพิ่ม__metaclass__ = Singleton
!
class Singleton(type):
def __init__(self, *args, **kwargs):
super(Singleton, self).__init__(*args, **kwargs)
self.__instance = None
def __call__(self, *args, **kwargs):
if self.__instance is None:
self.__instance = super(Singleton, self).__call__(*args, **kwargs)
return self.__instance
อย่างไรก็ตามนี่อาจเป็นเวทย์มนตร์ที่ลึกกว่าที่รับประกันจริงสำหรับสถานการณ์นี้!