Python类调用逻辑:__new__检查、__call__关联等技术疑问咨询
isinstance Check in Class Instantiation Let’s break down your questions one by one to demystify what’s happening when you call a class like C(23):
1. Why is the isinstance(x, C) check necessary?
The default object.__new__(C) does return an instance of C, but __new__ can be overridden to return any object—not just instances of the class it’s defined in. Python intentionally allows this flexibility, and the check ensures we only run __init__ if we actually have an instance of C (or a subclass) to initialize.
For example, consider a subclass of int that returns a regular int instead of its own type:
class MyInt(int): def __new__(cls, value): # Return a standard int, not a MyInt instance return int.__new__(int, value) def __init__(self, value): print("This __init__ will never run!") x = MyInt(23) print(type(x)) # Output: <class 'int'>
Here, x isn’t an instance of MyInt, so the isinstance check fails, and __init__ never executes.
2. Doesn’t __new__ have to return a C type object?
Nope—Python doesn’t enforce this. You can use __new__ as a factory method to return instances of other classes, or even existing objects (like in the singleton pattern). The default implementation from object returns a new uninitialized instance of the class, but custom implementations can deviate from this entirely.
3. What happens if the check fails?
If x isn’t an instance of C, the type(x).__init__(x, 23) line is skipped. This means the initialization step is ignored for non-C instances.
For example, if you return a different immutable type like str, that type’s __init__ won’t be called here either—since we only trigger initialization for objects that belong to the C class hierarchy.
4. Is __new__ called inside the class’s __call__() method?
Absolutely! Classes are callable objects because they’re instances of type, and type defines a __call__ method. When you invoke C(23), here’s what type.__call__ does under the hood:
- Calls
C.__new__(C, 23)to create a potential instance - Checks if the result is an instance of
C(viaisinstance) - If yes, calls
type(x).__init__(x, 23)(which isC.__init__(x, 23)ifxis aCinstance) - Returns the final object
What you might have missed
The key insight is that __new__ isn’t strictly tied to creating instances of its own class. Python’s design prioritizes flexibility here, letting __new__ act as a factory. The isinstance check ensures we don’t waste time initializing objects that aren’t actually part of the class hierarchy we’re working with.
内容的提问来源于stack exchange,提问作者Algo

