关于Python Enum类实例化时调用元类__call__而非Enum类__new__方法的技术问询
Great question! This gets to the heart of how Python handles class instantiation and the special design of Enums. Let's break this down step by step:
1. How regular class instantiation works
First, let's recap the normal flow when you create an instance of a regular class (like obj = MyClass()):
- When you call the class, you're actually invoking the metaclass's
__call__method. For most classes, the metaclass istype, sotype.__call__(MyClass)runs under the hood. type.__call__then does two main things:- Calls
MyClass.__new__(MyClass, ...)to create a new instance. - Calls
MyClass.__init__(instance, ...)to initialize that instance.
- Calls
2. Enum's metaclass overrides call for singleton behavior
Enums are designed to be singletons—each enum member is a unique, pre-defined instance that can't be recreated. That's where EnumMeta comes in: it overrides the __call__ method to enforce this behavior.
When you try to "instantiate" an Enum (like Color(1)), here's what EnumMeta.__call__ does instead of the regular flow:
- It first checks if there's already an enum member with the given value (or name, depending on how you call it).
- If that member exists, it returns the pre-existing instance instead of creating a new one.
- If no matching member exists, it raises a
ValueError(since Enums don't allow arbitrary new instances).
3. Enum.new is for creating enum members (not user instantiation)
So when does Enum.__new__ get called? It's used during the class definition phase, not when you try to instantiate the Enum later:
- When you define an Enum subclass (like
class Color(Enum): RED = 1),EnumMeta.__new__(the metaclass's__new__method, which creates the Enum class itself) iterates over all the class attributes that are enum members. - For each member, it calls
Enum.__new__(Color, ...)to create the actual instance of the enum member (likeColor.RED), then binds that instance to the class as an attribute.
Example to clarify
Let's use a concrete example:
from enum import Enum class Color(Enum): RED = 1 BLUE = 2
- When this code runs,
EnumMeta.__new__creates theColorclass. It processesRED = 1andBLUE = 2, callingColor.__new__(Color, 1)to make theREDinstance, and same forBLUE. - Later, if you write
my_color = Color(1), this triggersEnumMeta.__call__(Color, 1). This method looks up the existing instance with value 1 (Color.RED) and returns it—no call toEnum.__new__happens here.
Bottom line
Enum.__new__is responsible for creating the fixed set of enum members when the Enum class is defined.EnumMeta.__call__is responsible for retrieving those pre-existing members when you "instantiate" the Enum class later.
This design ensures that Enum members are singletons and can't be duplicated, which is core to how Enums are meant to be used in Python.
内容的提问来源于stack exchange,提问作者Allen Huang

