Isinstance detection process from the source code

Start

The built-in method isinstance(object, classinfo) can be used to determine if an object is an instance of a class. But have you ever thought about how the object of the duck protocol is to judge? For example, the parent class of the list class is following the object class, but is returned by isinstance([], typing.Iterable). Is the list an iterable subclass?

According to the description of PEP 3119, the inspection of the instance is allowed to be overloaded:

The primary mechanisms proposed here is to overload overloading the built-in functions isinstance() and issubclass(). The overloading works as follows: The call isinstance(x, C) first checks whether C.__instancecheck__ exists, andif so, calls C. __instancecheck__(x) instead of its normal implementation.

The meaning of this passage is that when calling isinstance(x, C) to detect, it will first check for the presence of C.instancecheck, if it exists, then call C.instancecheck(x), and the returned result is the result of the instance detection. There is no way to judge.

This method helps us to check the duck type. I tested it with code.

classSizeable(object):

Def __instancecheck__(cls, instance):

Print("__instancecheck__ call")

Return hasattr(instance, "__len__")

Class B(object):

Pass

b = B()

Print(isinstance(b, Sizeable)) # output:False

Only False is printed, and instancecheck is not called. How is this going. Visible document description is not clear. The principle of breaking the casserole in the end I observed the isinstance detection process from the source code.

Isinstance detection process from source code

The content of this part may be more difficult. If readers find it difficult to read, they can skip and look directly at the conclusion. The source of isinstance is in the abstract.c file:

[abstract.c]

Int

PyObject_IsInstance(PyObject *inst, PyObject *cls)

{

_Py_IDENTIFIER(__instancecheck__);

PyObject *checker;

/* Quick test for an exact match */

If (Py_TYPE(inst) == (PyTypeObject *)cls)

Return1;

....

}

Py_TYPE (inst) == (PyTypeObject *)cls This is a quick match, equivalent to type(inst) is cls, this fast way only if inst = cls() matches successfully and does not go first Checking instancecheck, so there is something wrong with the document. Continue to look down at the source code:

/* We know what type's __instancecheck__ does. */

If (PyType_CheckExact(cls)) {

Return recursive_isinstance(inst, cls);

}

Expand the macro PyType_CheckExact :

[object.h]

#definePyType_CheckExact(op) (Py_TYPE(op) == &PyType_Type)

In other words, cls is a class constructed directly from type. Except for the metaclass specified in the class declaration, it is basically constructed directly by type. From the test code, it is determined that the judgment is established and enters recursiveisinstance. But in this function I didn't find the code for instancecheck. The recursiveisinstance's decision logic is roughly:

Def recursive_isinstance(inst, cls):

Return pyType_IsSubtype(inst, cls)

Def pyType_IsSubtype(a, b):

For mro in a.__class__.__mro__:

If mro is b:

returnTrue

returnFalse

It is judged from the order of inheritance of mro. mro is a tuple, which represents the order of inheritance of the class. The order of the attributes in this tuple also determines the order of the attributes. Go back to the PyObject_IsInstance function and look down:

If (PyTuple_Check(cls)) {

...

}

This is the case when the second argument to instance(x, C) is a tuple, and the way to handle it is to call PyObject_IsInstance(inst, item) recursively. Continue to look down:

Checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__);

If (checker != NULL) {

Res = PyObject_CallFunctionObjArgs(checker, inst, NULL);

Ok = PyObject_IsTrue(res);

Return ok;

}

Obviously, this is the place to get instancecheck, in order to let the check flow come here, the defined class should indicate the metaclass. The rest is to track PyObjectLookupSpecial on it:

[typeobject.c]

PyObject *

_PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid)

{

PyObject *res;

Res = _PyType_LookupId(Py_TYPE(self), attrid);

// handle callbacks if there are callbacks

// ...

Return res;

}

Take PyTYPE(self), which means that the specified metaclass needs to define instancecheck. After the property is obtained, the content called is the user-defined overload method through PyObjectCallFunctionObjArgs call.

Inspection mechanism summary

At this point, the isinstance detection process is basically clear. To facilitate understanding, it also benefits from Python's strong self-explanatory ability. I use Python code to simplify the isinstance process:

Def _isinstance(x, C):

# Quick match

If type(x) is C:

returnTrue

# If the class is constructed directly from the metaclass type

If type(C) is type:

Return C in x.__class__.__mro__

# If the second parameter is a tuple, call recursively

If type(C) is tuple:

For item in C:

r = _isinstance(x, item)

If r:

Return r

# User-defined detection rules

If hasattr(C, "__instancecheck__"):

Return C.__instancecheck__(x)

# Default behavior

Return C in x.__class__.__mro__

There are five steps in the judgment process, and the user-defined instancecheck is later. This detection process is mainly performed by the default behavior. User behavior is not preferred.

Overload isinstance(x, C)

Therefore, if you want to overload isinstance(x, C) so that the user can customize the judgment result, you need to meet the following conditions:

x objects cannot be directly instantiated by C;

Class C specified metaclass ;

The instancecheck is defined in the specified metaclass class.

After satisfying these conditions, for example, how to judge the duck agreement is more clear:

classMetaSizeable(type):

Def __instancecheck__(cls, instance):

Print("__instancecheck__ call")

Return hasattr(instance, "__len__")

classSizeable(metaclass=MetaSizeable):

Pass

Class B(object):

Pass

b = B()

Print(isinstance(b, Sizeable)) # output: False

Print(isinstance([], Sizeable)) # output: True

This test environment Python3.6.0

High Voltage Power Supplies

iDealTek-Electronics has accumulated rich application experience and design technical knowledge in the field of High-voltage power supplies, from Linear High Voltage Power Supplies based on power frequency transformers to Switching High Voltage power supplies based on IGBT components, from 60KV, 1KW High Voltage Power Module, to 5KV ~ 40KV, 1KW 2U Laboratory High-voltage power supplies, and to 5KV ~ 60KV, 2KW 4U and 5KV ~ 100KV, 6U rack-mounted capacitor charging high-voltage power supplies, and then to floor-standing cabinet-type high-current high-power high-voltage power supplies, all our high voltage power supplies are featured for high reliability, excellent high-voltage output stability and low-ripple electronic characteristics.
Ccp 6u High Voltage Capacitor Charging Power Supplies Side PanelCcps 6u High Voltage Power Supplies FrontCcps Cabinet Type High Voltage Power Supplies
Through the reliable and durable operation panel on the front panel of the high-voltage power supply, the output voltage and current can be easily set and controlled. The high-precision LED or LCD ensures intuitive and high-precision high-voltage output measurement functions. Our high-voltage power supplies can be equipped with a wealth of remote-control interfaces, such as RS232 / RS485 /DB15 / DB25 / DB50 analog signal interface, etc. for remote high-voltage enable and inhibit, high-voltage output control programming and data monitoring.

Our HV power supplies have complete built-in protection functions, such as overvoltage protection, ARC protection, load discharge protection, over heat protection, etc. The protection mechanism can start in transient time to ensure the safety and reliability of the power supply itself and customer loads under high-voltage output.
Hps High Power High Voltage Power Supplies
At present, our high voltage power supplies are widely used in high-voltage laboratories, capacitor charging, electron beam, ion implantation, FUSION power generation and other industries.

HV Power Supplies, High-voltage Power Supplies, High Voltage DC Power Supplies, HV PSU, High Voltage Power Module

Yangzhou IdealTek Electronics Co., Ltd. , https://www.idealtekpower.com