[ad_1]
You have simply made a category.
You made a __init__
methodology.
Now what?
Python consists of tons of dunder strategies (“double underscore” strategies) which permit us to deeply customise how our customized courses work together with Python’s many options.
What dunder strategies might you add to your class to make it pleasant for different Python programmers who use it?
Let’s check out each dunder methodology in Python, with a give attention to when every methodology is helpful.
Word that the Python documentation refers to those as particular strategies and notes the synonym “magic methodology” however very hardly ever makes use of the time period “dunder methodology”.
Nonetheless, “dunder methodology” is a reasonably frequent Python colloquialism, as famous in my unofficial Python glossary.
You should use the hyperlinks scattered all through this web page for extra particulars on any specific dunder methodology.
For a listing of all of them, see the cheat sheet within the remaining part.
The three important dunder strategies ๐
There are 3 dunder strategies that most courses ought to have: __init__
, __repr__
, and __eq__
.
Operation | Dunder Methodology Name | Returns |
---|---|---|
T(a, b=3) |
T.__init__(x, a, b=3) |
None |
repr(x) |
x.__repr__() |
str |
x == y |
x.__eq__(y) |
Sometimes bool |
The __init__
methodology is the initializer (to not be confused with the constructor), the __repr__
methodology customizes an object’s string illustration, and the __eq__
methodology customizes what it means for objects to be equal to at least one one other.
The __repr__
methodology is especially useful on the the Python REPL and when debugging.
Equality and hashability ๐ฐ
Along with the __eq__
methodology, Python has 2 different dunder strategies for figuring out the “worth” of an object in relation to different objects.
Operation | Dunder Methodology Name | Returns |
---|---|---|
x == y |
x.__eq__(y) |
Sometimes bool |
x != y |
x.__ne__(y) |
Sometimes bool |
hash(x) |
x.__hash__() |
int |
Python’s __eq__
methodology usually returns True
, False
, or NotImplemented
(if objects cannot be in contrast).
The default __eq__
implementation depends on the is
operator, which checks for identification.
The default implementation of __ne__
calls __eq__
and negates any boolean return worth given (or returns NotImplemented
if __eq__
did).
This default habits is often “ok”, so you may nearly by no means see __ne__
applied.
Hashable objects can be utilized as keys in dictionaries or values in units.
All objects in Python are hashable by default, however in the event you’ve written a customized __eq__
methodology then your objects will not be hashable and not using a customized __hash__
methodology.
However the hash worth of an object must not ever change or unhealthy issues will occur so usually solely immutable objects implement __hash__
.
For implementing equality checks, see __eq__
in Python.
For implementing hashability, see making hashable objects in Python.
Orderability โ๏ธ
Python’s comparability operators (<
, >
, <=
, >=
) can all be overloaded with dunder strategies as properly.
The comparability operators additionally energy features that depend on the relative ordering of objects, like sorted
, min
, and max
.
Operation | Dunder Methodology Name | Returns |
---|---|---|
< |
__lt__ |
Sometimes bool |
> |
__gt__ |
Sometimes bool |
<= |
__le__ |
Sometimes bool |
>= |
__ge__ |
Sometimes bool |
In case you plan to implement all of those operators within the typical method (the place x < y
can be the identical as asking y >= x
) then the total_ordering
decorator from Python’s functools
module will turn out to be useful.
Kind conversions and string formatting โ๏ธ
Python has a variety of dunder strategies for changing objects to a distinct kind.
Perform | Dunder Methodology Name | Returns |
---|---|---|
str(x) |
x.__str__() |
str |
bool(x) |
x.__bool__() |
bool |
int(x) |
x.__int__() |
int |
float(x) |
x.__float__() |
float |
bytes(x) |
x.__bytes__() |
bytes |
complicated(x) |
x.__complex__() |
complicated |
f"{x:s}" |
x.__format__(s) |
str |
repr(x) |
x.__repr__() |
str |
The __bool__
operate is used for truthiness checks, although __len__
is used as a fallback.
In case you wanted to make an object that acts like a quantity (like decimal.Decimal
or fractions.Fraction
), you may need to implement __int__
, __float__
, and __complex__
so your objects could be transformed to different numbers.
In case you wished to make an object that may very well be utilized in a memoryview
or might in any other case be transformed to bytes
, you may need a __bytes__
methodology.
The __format__
and __repr__
strategies are totally different string conversion flavors.
Most string conversions rely the __str__
methodology, however the default __str__
implementation merely calls __repr__
.
The __format__
methodology is utilized by all f-string conversions, by the str
class’s format
methodology, and by the (hardly ever used) built-in format
operate.
This methodology permits datetime
objects to assist customized format specifiers.
Context managers ๐ช
A context supervisor is an object that can be utilized in a with
block.
Use | Dunder Methodology Name | Returns |
---|---|---|
with block enter |
x.__enter__() |
A worth given to as |
with block exit |
x.__exit__(exc_type, exc, traceback) |
Truthy/falsey worth |
For extra on context managers see, what’s a context supervisor and making a context supervisor.
Containers and collections ๐๏ธ
Collections (a.okay.a. containers) are basically information constructions or objects that act like information stuctures.
Lists, dictionaries, units, strings, and tuples are all examples of collections.
Operation | Dunder Methodology Name | Return Kind | Applied |
---|---|---|---|
len(x) |
x.__len__() |
integer | Quite common |
iter(x) |
x.__iter__() |
iterator | Quite common |
for merchandise in x: ... |
x.__iter__() |
iterator | Quite common |
x[a] |
x.__getitem__(a) |
any object | Widespread |
x[a] = b |
x.__setitem__(a, b) |
None | Widespread |
del x[a] |
x.__delitem__(a) |
None | Widespread |
a in x |
x.__contains__(a) |
bool | Widespread |
reversed(x) |
x.__reversed__() |
iterator | Widespread |
subsequent(x) |
x.__next__() |
any object | Unusual |
x[a] |
x.__missing__(a) |
any object | Unusual |
operator.length_hint(x) |
x.__length_hint__() |
integer | Unusual |
The __iter__
methodology is utilized by the iter
operate and for all types of iteration: for
loops, comprehensions, tuple unpacking, and utilizing *
for iterable unpacking.
Whereas the __iter__
methodology is critical for making a customized iterable, the __next__
methodology is critical for making a customized iterator (which is way much less frequent).
The __missing__
methodology is barely ever referred to as by the dict
class on itself, except one other class decides to implement __missing__
.
The __length_hint__
methodology provides a size guess for constructions which don’t assist __len__
in order that lists or different constructions could be pre-sized extra effectively.
Additionally see: the iterator protocol, implementing __len__
, and implementing __getitem__
.
Callability โ๏ธ
Features, courses, and all different callable objects depend on the __call__
methodology.
Operation | Dunder Methodology Name | Return Kind |
---|---|---|
x(a, b=c) |
x.__call__(a, b=c) |
any object |
When a category is known as, its metaclass‘s __call__
methodology is used.
When a category occasion is known as, the category’s __call__
methodology is used.
For extra on callability, see Callables: Python’s “features” are generally courses.
Arithmetic operators โ
Python’s dunder strategies are sometimes described as a device for “operator overloading”.
Most of this “operator overloading” comes within the type of Python’s numerous arithmetic operators.
There are two methods to interrupt down the arithmetic operators:
- Mathematical (e.g.
+
,-
,*
,/
,%
) versus bitwise (e.g.&
,|
,^
,>>
,~
) - Binary (between 2 values, like
x + y
) versus unary (earlier than 1 worth, like+x
)
The mathematical operators are way more frequent than the bitwise ones and the binary ones are a bit extra frequent than the unary ones.
These are the binary mathematical arithmetic operators:
Operation | Left-Hand Methodology | Proper-Hand Methodology | Description |
---|---|---|---|
x + y |
__add__ |
__radd__ |
Add / Concatenate |
x - y |
__sub__ |
__rsub__ |
Subtract |
x * y |
__mul__ |
__rmul__ |
Multiply |
x / y |
__truediv__ |
__rtruediv__ |
Divide |
% |
__mod__ |
__rmod__ |
Modulo |
x // y |
__floordiv__ |
__rfloordiv__ |
Integer division |
** |
__pow__ |
__rpow__ |
Exponentiate |
x @ y |
__matmul__ |
__rmatmul__ |
Matrix multiply |
Every of those operators consists of left-hand and right-hand strategies.
If x.__add__(y)
returns NotImplemented
, then y.__radd__(x)
shall be tried.
See arithmetic dunder strategies for extra.
These are the binary bitwise arithmetic operators:
Operation | Left-Hand Methodology | Proper-Hand Methodology | Description |
---|---|---|---|
x & y |
__and__ |
__rand__ |
AND |
x | y |
__or__ |
__ror__ |
OR |
x ^ y |
__xor__ |
__rxor__ |
XOR |
x >> y |
__rshift__ |
__rrshift__ |
Proper-shift |
x << y |
__lshift__ |
__rlshift__ |
Left-shift |
These are the Python’s unary arithmetic operators:
Operation | Dunder Methodology | Selection | Description |
---|---|---|---|
-x |
__neg__ |
Mathematical | Negate |
+x |
__pos__ |
Bitwise | Affirm |
~x |
__invert__ |
Bitwise | Invert |
The unary +
operator usually has no impact, although some objects use it for a selected operation.
For instance utilizing +
on collections.Counter
objects will take away non-positive values.
Python’s arithmetic operators are sometimes used for non-arithmetic ends: sequences use +
to concatenate and *
to self-concatenate and units use &
for intersection, |
for union, -
for uneven distinction, and ^
for symmetric distinction.
Arithmetic operators are generally overloaded for extra artistic makes use of too.
For instance, pathlib.Path
objects use /
to create little one paths.
In-place arithmetic operations โป๏ธ
Python consists of many dunder strategies for in-place operations.
In case you’re making a mutable object that helps any of the arithmetic operations, you may need to implement the associated in-place dunder methodology(s) as properly.
Operation | Dunder Methodology Name | Returns |
---|---|---|
x += y |
x.__iadd__(y) |
Sometimes self |
x -= y |
x.__isub__(y) |
Sometimes self |
x *= y |
x.__imul__(y) |
Sometimes self |
x /= y |
x.__itruediv__(y) |
Sometimes self |
x %= y |
x.__imod__(y) |
Sometimes self |
x //= y |
x.__ifloordiv__(y) |
Sometimes self |
x **= y |
x.__ipow__(y) |
Sometimes self |
x @= y |
x.__imatmul__(y) |
Sometimes self |
x &= y |
x.__iand__(y) |
Sometimes self |
x |= y |
x.__ior__(y) |
Sometimes self |
x ^= y |
x.__ixor__(y) |
Sometimes self |
x >>= y |
x.__irshift__(y) |
Sometimes self |
x <<= y |
x.__ilshift__(y) |
Sometimes self |
All of Python’s binary arithmetic operators work in augmented project statements, which contain utilizing an operator adopted by the =
signal to assign to an object whereas performing an operation on it.
Augmented assignments on mutable objects are anticipated to mutate the unique object, because of the mutable object implementing the suitable dunder methodology for in-place arithmetic.
When no dunder methodology is discovered for an in-place operation, Python performs the operation adopted by an project.
Immutable objects usually do not implement dunder strategies for in-place operations, since they need to return a brand new object as a substitute of fixing the unique.
Constructed-in math features ๐งฎ
Python additionally consists of dunder strategies for a lot of math-related features, each built-in features and a few features within the math
library.
Operation | Dunder Methodology Name | Returns |
---|---|---|
divmod(x, y) |
x.__divmod__(y) |
2-item tuple |
abs(x) |
x.__abs__() |
float |
sequence[x] |
x.__index__() |
int |
spherical(x) |
x.__round__() |
Quantity |
math.trunc(x) |
x.__trunc__() |
Quantity |
math.ground(x) |
x.__floor__() |
Quantity |
math.ceil(x) |
x.__ceil__() |
Quantity |
Python’s divmod
operate performs integer division (//
) and a modulo operation (%
) on the identical time.
The __index__
methodology is for making integer-like objects.
This methodology losslessly converts to an integer, in contrast to __int__
which can carry out a “lossy” integer conversion (e.g. from float
to int
).
It is utilized by operations that require true integers, corresponding to slicing, indexing, and bin
, hex
, and oct
features (instance).
Attribute entry ๐
Python even consists of dunder strategies for controlling what occurs whenever you entry, delete, or assign any attribute on an object!
Operation | Dunder Methodology Name | Returns |
---|---|---|
x.lacking |
x.__getattr__("lacking") |
Attribute worth |
x.something |
x.__getattribute__("something") |
Attribute worth |
x.factor = worth |
x.__setattr__("factor", worth) |
None |
del x.factor |
x.__delattr__("factor") |
None |
dir(x) |
x.__dir__() |
Record of strings |
The __getattribute__
methodology is known as for each attribute entry, whereas the __getattr__
methodology is barely referred to as after Python fails to discover a given attribute.
All methodology calls and attribute accesses name __getattribute__
so implementing it accurately is difficult (because of unintended recursion).
The __dir__
methodology ought to return an iterable of attribute names (as strings).
When the dir
operate calls __dir__
, it converts the returned iterable right into a sorted record (like sorted
does).
The built-in getattr
, setattr
, and delattr
features correspond to the dunder strategies of the identical identify, however they’re solely supposed for dynamic attribute entry (not all attribute accesses).
Now we’re stepping into the actually uncommon dunder strategies.
Python consists of many dunder strategies for metaprogramming-related options.
Applied on | Operation | Dunder Methodology Name | Returns |
---|---|---|---|
Metaclasses | class T: ... |
kind(base).__prepare__() |
mapping |
Metaclasses | isinstance(x, T) |
T.__instancecheck__(x) |
bool |
Metaclasses | issubclass(U, T) |
T.__subclasscheck__(U) |
bool |
Any class | class U(T): ... |
T.__init_subclass__(U) |
None |
Any class | (Referred to as manually) | T.__subclasses__() |
record |
Any class | class U(x): ... |
x.__mro_entries__([x]) |
tuple |
Any class | T[y] |
T.__class_getitem__(y) |
an merchandise |
The __prepare__
methodology customizes the dictionary that is used for a category’s preliminary namespace.
That is used to pre-populate dictionary values or customise the dictionary kind (foolish instance).
The __instancecheck__
and __subclasscheck__
strategies override the performance of isinstance
and issubclass
.
Python’s ABCs use these to apply goose typing (duck typing whereas kind checking).
The __init_subclass__
methodology permits courses to hook into subclass initialization (instance).
Lessons additionally have a __subclasses__
methodology (on their metaclass) nevertheless it’s not usually overridden.
Python calls __mro_entries__
throughout class inheritance for any base courses that aren’t truly courses.
The typing.NamedTuple
operate makes use of this to fake it is a class (see right here).
The __class_getitem__
methodology permits a category to be subscriptable (with out its metaclass needing a __getitem__
methodology).
That is usually used for enabling fancy kind annotations (e.g. record[int]
).
Descriptors ๐ท๏ธ
Descriptors are objects that, when hooked up to a category, can hook into the entry of the attribute identify they’re hooked up to on that class.
Operation | Dunder Methodology Name | Returns |
---|---|---|
class T: x = U() |
T.x.__set_name__(T, 'x') |
None |
t.x |
T.x.__get__(t, T) |
The worth |
t.x = y |
T.x.__set__(t, y) |
None |
del t.x |
T.x.__del__(t) |
None |
The descriptor protocol is principally a function that exists to make Python’s property
decorator work, although it’s also utilized by a variety of third-party libraries.
Buffers ๐พ
Implementing a low-level reminiscence array?
You want Python’s buffer protocol.
Operation | Dunder Methodology Name | Returns |
---|---|---|
memoryview(x) |
x.__buffer__(flags) |
memoryview |
del memoryview(x) |
x.__release_buffer__(m) |
None |
The __release_buffer__
methodology is known as when the buffer that is returned from __buffer__
is deleted.
Python’s buffer protocol is usually applied in C, because it’s meant for low degree objects.
Asynchronous operations ๐คน
Wish to implement an asynchronous context supervisor?
You want these dunder strategies:
__aenter__
: identical to__enter__
, nevertheless it returns an awaitable object__aexit__
: identical to__exit__
, nevertheless it returns an awaitable object
Want assist asynchronous iteration?
You want these dunder strategies:
__aiter__
: should return an asynchronous iterator__anext__
: like__next__
or non-async iterators, however this should return an awaitable object and this could increaseStopAsyncIteration
as a substitute ofStopIteration
Have to make your individual awaitable object?
You want this dunder methodology:
__await__
: returns an iterator
I’ve little expertise with customized asynchronous objects, so look elsewhere for extra particulars.
Building and finalizing ๐ญ
The previous few dunder strategies are associated to object creation and destruction.
Operation | Dunder Methodology Name | Returns |
---|---|---|
T(a, b=3) |
T.__new__(T, a, b=3) |
New occasion (x ) |
T(a, b=3) |
T.__init__(x, a, b=3) |
None |
del x |
x.__delete__() |
None |
Calling a category returns a brand new class occasion because of the __new__
methodology.
The __new__
methodology is Python’s constructor methodology, although in contrast to constructors in lots of programming languages, you need to nearly by no means outline your individual __new__
methodology.
To manage object creation, want the initializer (__init__
), not the constructor (__new__
).
This is an odd __new__
instance.
You would consider __del__
as a “destructor” methodology, although it is truly referred to as the finalizer methodology.
Simply earlier than an object is deleted, its __del__
methodology is known as (instance).
Recordsdata implement a __del__
methodology that closes the file and any binary file buffer that it might be linked to.
Library-specific dunder strategies ๐งฐ
Some normal library modules outline customized dunder strategies that are not used anyplace else:
- dataclasses assist a
__post_init__
methodology abc.ABC
courses have a__subclasshook__
methodology whichabc.ABCMeta
calls in its__subclasscheck__
methodology (extra in goose typing)- Path-like objects have a
__fspath__
methodology, which returns the file path as a string - Python’s
copy
module will use the__copy__
and__deepcopy__
strategies if current - Pickling depends on
__getnewargs_ex__
or__getargs__
, although__getstate__
and__setstate__
can customise additional and__reduce__
or__reduce_ex__
are even lower-level sys.getsizeof
depends on the__sizeof__
methodology to get an object’s dimension (in bytes)
Dunder attributes ๐
Along with dunder strategies, Python has many non-method dunder attributes.
Listed here are among the extra frequent dunder attributes you may see:
__name__
: identify of a operate, courses, or module__module__
: module identify for a operate or class__doc__
: docstring for a operate, class, or module__class__
: an object’s class (name Python’skind
operate as a substitute)__dict__
: most objects retailer their attributes right here (see the place are attributes saved?)__slots__
: courses utilizing this are extra reminiscence environment friendly than courses utilizing__dict__
__match_args__
: courses can outline a tuple noting the importance of positional attributes when the category is utilized in structural sample matching (match
–case
)__mro__
: a category’s methodology decision order used when for attribute lookups andtremendous()
calls__bases__
: the direct father or mother courses of a category__file__
: the file that outlined the module object (although not all the time current!)__wrapped__
: features adorned withfunctools.wraps
use this to level to the unique operate__version__
: generally used for noting the model of a bundle__all__
: modules can use this to customise the habits offrom my_module import *
__debug__
: working Python with-O
units this toFalse
and disables Python’sassert
statements
These are solely the extra generally seen dunder attributes.
Listed here are some extra:
- Features have
__defaults__
,__kwdefaults__
,__code__
,__globals__
, and__closure__
- Each features and courses have
__qualname__
,__annotations__
, and__type_params__
- Occasion strategies have
__func__
and__self__
- Modules can also have
__loader__
,__package__
,__spec__
, and__cached__
attributes - Packages have a
__path__
attribute - Exceptions have
__traceback__
,__notes__
,__context__
,__cause__
, and__suppress_context__
- Descriptors use
__objclass__
- Metaclasses use
__classcell__
- Python’s
weakref
module makes use of__weakref__
- Generic aliases have
__origin__
,__args__
,__parameters__
, and__unpacked__
- The
sys
module has__stdout__
and__stderr__
which level to the uniquestdout
andstderr
variations
Moreover, these dunder attributes are utilized by numerous normal library modules: __covariant__
, __contravariant__
, __infer_variance__
, __bound__
, __constraints__
.
And Python features a built-in __import__
operate which you are not supposed to make use of (importlib.import_module
is most well-liked) and CPython has a __builtins__
variable that factors to the builtins
module (however that is an implementation element and builtins
needs to be explicitly imported when wanted as a substitute).
Additionally importing from the __future__
module can allow particular Python function flags and Python will search for a __main__
module inside packages to make them runnable as CLI scripts.
And that is simply most of the dunder attribute names you may discover floating round in Python. ๐ต
Each dunder methodology: a cheat sheet โญ
That is each Python dunder methodology organized in classes and ordered very roughly by the mostly seen strategies first.
Some caveats are famous beneath.
Class | Operation | Dunder Methodology Name | Returns |
---|---|---|---|
Object Creation | x = T(a, b) |
x.__init__(a, b) |
None |
Object Creation | x = T(a, b) |
T.__new__(T, a, b) |
New occasion (x ) |
Finalizer | del x (ish) |
x.__del__() |
None |
Comparisons | x == y |
x.__eq__(y) |
Sometimes bool |
Comparisons | x != y |
x.__ne__(y) |
Sometimes bool |
Comparisons | x < y |
x.__lt__(y) |
Sometimes bool |
Comparisons | x > y |
x.__rt__(y) |
Sometimes bool |
Comparisons | x <= y |
x.__le__(y) |
Sometimes bool |
Comparisons | x >= y |
x.__ge__(y) |
Sometimes bool |
Hashability | hash(x) |
x.__hash__() |
int |
Conversions | repr(x) |
x.__repr__() |
All the time str |
Conversions | str(x) |
x.__str__() |
All the time str |
Conversions | bool(x) |
x.__bool__() |
All the time bool |
Conversions | int(x) |
x.__int__() |
All the time int |
Conversions | float(x) |
x.__float__() |
All the time float |
Conversions | bytes(x) |
x.__bytes__() |
All the time bytes |
Conversions | complicated(x) |
x.__complex__() |
All the time complicated |
Conversions | format(x, s) |
x.__format__(s) |
All the time str |
Context Managers | with x as c: |
x.__enter__() |
The c object |
Context Managers | with x as c: |
x.__exit__() |
Truthy/falsey worth |
Collections | len(x) |
x.__len__() |
int |
Collections | iter(x) |
x.__iter__() |
An iterator |
Collections | x[a] |
x.__getitem__(a) |
|
Collections | x[a] = b |
x.__setitem__(a, b) |
None |
Collections | del x[a] |
x.__delitem__(a) |
None |
Collections | a in x |
x.__contains__(a) |
bool |
Collections | reversed(x) |
x.__reversed__() |
An iterator |
Collections | subsequent(x) |
x.__next__() |
Subsequent iterator merchandise |
Collections | x[a] |
x.__missing__(a) |
|
Collections | x.__length_hint__() |
int |
|
Arithmetic | x + y |
x.__add__(y) |
|
Arithmetic | x + y |
y.__radd__(x) |
|
Arithmetic | x - y |
x.__sub__(y) |
|
Arithmetic | x - y |
y.__rsub__(x) |
|
Arithmetic | x * y |
x.__mul__(y) |
|
Arithmetic | x * y |
y.__rmul__(x) |
|
Arithmetic | x / y |
x.__truediv__(y) |
|
Arithmetic | x / y |
y.__rtruediv__(x) |
|
Arithmetic | x % y |
x.__mod__(y) |
|
Arithmetic | x % y |
y.__rmod__(x) |
|
Arithmetic | x // y |
x.__floordiv__(y) |
|
Arithmetic | x // y |
y.__rfloordiv__(x) |
|
Arithmetic | x ** y |
x.__pow__(y) |
|
Arithmetic | x ** y |
y.__rpow__(x) |
|
Arithmetic | x @ y |
x.__matmul__(y) |
|
Arithmetic | x @ y |
y.__rmatmul__(x) |
|
Arithmetic | x & y |
x.__and__(y) |
|
Arithmetic | x & y |
y.__rand__(x) |
|
Arithmetic | x | y |
x.__or__(y) |
|
Arithmetic | x | y |
y.__ror__(x) |
|
Arithmetic | x ^ y |
x.__xor__(y) |
|
Arithmetic | x ^ y |
y.__rxor__(x) |
|
Arithmetic | x >> y |
x.__rshift__(y) |
|
Arithmetic | x >> y |
y.__rrshift__(x) |
|
Arithmetic | x << y |
x.__lshift__(y) |
|
Arithmetic | x << y |
y.__rlshift__(x) |
|
Arithmetic | -x |
x.__neg__() |
|
Arithmetic | +x |
x.__pos__() |
|
Arithmetic | ~x |
x.__invert__() |
|
Math features | divmod(x, y) |
x.__divmod__(y) |
2-item tuple |
Math features | abs(x) |
x.__abs__() |
float |
Math features | x.__index__() |
int |
|
Math features | spherical(x) |
x.__round__() |
Quantity |
Math features | math.trunc(x) |
x.__trunc__() |
Quantity |
Math features | math.ground(x) |
x.__floor__() |
Quantity |
Math features | math.ceil(x) |
x.__ceil__() |
Quantity |
Task | x += y |
x.__iadd__(y) |
Sometimes self |
Task | x -= y |
x.__isub__(y) |
Sometimes self |
Task | x *= y |
x.__imul__(y) |
Sometimes self |
Task | x /= y |
x.__itruediv__(y) |
Sometimes self |
Task | x %= y |
x.__imod__(y) |
Sometimes self |
Task | x //= y |
x.__ifloordiv__(y) |
Sometimes self |
Task | x **= y |
x.__ipow__(y) |
Sometimes self |
Task | x @= y |
x.__imatmul__(y) |
Sometimes self |
Task | x &= y |
x.__iand__(y) |
Sometimes self |
Task | x |= y |
x.__ior__(y) |
Sometimes self |
Task | x ^= y |
x.__ixor__(y) |
Sometimes self |
Task | x >>= y |
x.__irshift__(y) |
Sometimes self |
Task | x <<= y |
x.__ilshift__(y) |
Sometimes self |
Attributes | x.y |
x.__getattribute__('y') |
|
Attributes | x.y |
x.__getattr__('y') |
|
Attributes | x.y = z |
x.__setattr__('y', z) |
None |
Attributes | del x.y |
x.__delattr__('y') |
None |
Attributes | dir(x) |
x.__dir__() |
An iterable |
Descriptors | class T: x = U() |
T.x.__set_name__(T, 'x') |
None |
Descriptors | t.x |
T.x.__get__(t, T) |
|
Descriptors | t.x = y |
T.x.__set__(t, y) |
None |
Descriptors | del t.x |
T.x.__delete__(t) |
None |
Class stuff | class U(T): ... |
T.__init_subclass__(U) |
None |
Class stuff | class U(x): ... |
x.__mro_entries__([x]) |
tuple |
Class stuff | T[y] |
T.__class_getitem__(y) |
|
Metaclasses | class T: ... |
kind(base).__prepare__() |
dict /mapping |
Metaclasses | isinstance(x, T) |
T.__instancecheck__(x) |
bool |
Metaclasses | issubclass(U, T) |
T.__subclasscheck__(U) |
bool |
Async | await x (ish) |
x.__await__() |
An iterator |
Async | async with x: |
x.__aenter__() |
An awaitable |
Async | async with x: |
x.__aexit__() |
An awaitable |
Async | async for a in x: |
x.__aiter__() |
An awaitable |
Async | async for a in x: |
x.__anext__() |
An awaitable |
Buffers | memoryview(x) |
x.__buffer__(flags) |
memoryview |
Buffers | del memoryview(x) |
x.__release_buffer__(m) |
None |
The above desk has a slight however constant untruth.
Most of those dunder strategies usually are not truly referred to as on an object immediately however are as a substitute referred to as on the kind of that object: kind(x).__add__(x, y)
as a substitute of x.__add__(y)
.
This distinction principally issues with metaclass strategies.
I’ve additionally purposely excluded library-specific dunder strategies (like __post_init__
) and dunder strategies you are unlikely to ever outline (like __subclasses__
).
See these beneath.
Class | Operation | Dunder Methodology Name | Returns |
---|---|---|---|
Dataclasses | x = T(a, b) |
T.__post_init__(a, b) |
None |
Copying | copy.copy(x) |
x.__copy__() |
New object |
Copying | copy.deepcopy(x) |
x.__deepcopy__(memo) |
New object |
Pickling | pickle.dumps(x) |
x.__getnewargs__() |
A 2-item tuple |
Pickling | pickle.dumps(x) |
x.__getnewargs_ex__() |
A 2-item tuple |
Pickling | pickle.dumps(x) |
x.__getstate__() |
A significant state |
Pickling | pickle.dumps(x) |
x.__reduce__() |
A 2-6 merchandise tuple |
Pickling | pickle.dumps(x) |
x.__reduce_ex__(4) |
A 2-6 merchandise tuple |
Pickling | pickle.masses(b) |
x.__setstate__(state) |
None |
pathlib | os.fspath(x) |
p.__fspath__() |
str |
sys | sys.getsizeof(x) |
x.__sizeof__() |
int (dimension in bytes) |
Class stuff | None? | x.__subclasses__() |
Subclasses iterable |
ABCs | issubclass(U, T) |
T.__subclasshook__(U) |
bool |
So, Python consists of 103 “regular” dunder strategies, 12 library-specific dunder strategies, and a minimum of 52 different dunder attributes of varied sorts.
That is over 150 distinctive __dunder__
names!
I don’t advocate memorizing these: let Python do its job and lookup the dunder methodology or attribute that it’s essential implement/discover everytime you want it.
Remember that you are not meant to invent your individual dunder strategies.
Generally you may see third-party libraries that do invent their very own dunder methodology, however this is not inspired and it may be fairly complicated for customers who run throughout such strategies and assume they’re “actual” dunder strategies.
[ad_2]