How is the magic method architecture implemented in python? For example:

class SomeClass: def __init__(self, x): self.x = x def __repr__(self): return "({})".format(self.x) a = SomeClass(23) print(repr(a)) 

Those. How does the definition of calling the desired method of the desired class occur? ( repr class someclass)?

  • I didn’t quite understand your question, but you have a mistake in the code that has nothing to do with magic methods. Instead of the line return "({x})".format(x) should be return "({})".format(self.x) - Xander

3 answers 3

I will slightly add the previous answers. According to official documentation, here , special methods (this is what magic methods are called in documentation) is the python approach to operator overloading , which allows classes to define their behavior with respect to language operators . From this we can conclude that the interpreter has a "certain table" (let's call it that) correspondence of operators to the methods of the class. By overloading these methods, you can control the "behavior" of language operators relative to your class.

Also, if you make any special (magic) method None in a certain class, this will mean that the operation is not available for a certain class, and the corresponding operator applied to this class will return a TypeError.

The signature of the repr function for Python, you can see only in the source code in C. In the builtins.py module, it looks like this

 def repr(obj): # real signature unknown; restored from __doc__ """ Return the canonical string representation of the object. For many object types, including most builtins, eval(repr(obj)) == obj. """ pass 

But I think it is clear here.

By creating your class without heirs, you implicitly inherit the object class with all its special methods including repr . In the builtins.py module, it looks like this:

 class object: """ The most base type """ .... # ещё порядка 20 магических методов def __repr__(self, *args, **kwargs): # real signature unknown """ Return repr(self). """ pass 

Thus, one more conclusion can be made that even an “empty” user class is ready for use, in one form or another, by language operators (functions).

And a little more about compliance here

  • There were suggestions that everything comes from object. Thank you, now explained - khirnick
  • In Python 2, repr(obj) works even for objects that are not inherited from object . And conversely, objects of type object not required to define all special methods ( getattr(object(), '__add__') ). - jfs

The magic method is simply a method that is called implicitly, often to perform an operation on a type. For example, you can define a __bool__ method to indicate whether a True/False object is in a boolean context (if the default behavior, based on __len__ or True , is not appropriate). Many aspects of the behavior of objects in Python can be changed in this way. For example, the plumbum module , due to operator overloading, embeds sh -like language directly into Python :

 #!/usr/bin/env python from plumbum.cmd import awk, sort (awk["-f", "script.awk"] << "input data" | sort > "outfile.txt")() 

How is the magic method architecture implemented in python?
How is the definition of calling the right method of the desired class?

repr(SomeClass()) causes a call to SomeClass.__repr__ (if defined), because the documentation for the repr() function says so .

In general, nothing especially happens, for example, you can define your protocol:

 def quack(obj): return getattr(obj, 'quack', None)() 

Any object for which the quack() method is quack() , regardless of its base classes , can be passed to the quack () function:

 class Duck: def quack(self): return "Quack! Quack! Quack!" print(quack(Duck())) 

For other classes, TypeError thrown:

 try: quack(1) except TypeError: print("целое число не квакает") 

The difference of quack() from real magic methods is that double underlining is not used in the method name, by agreement , reserved for protocols defined by the language itself and there is no requirement to define a method in the class itself (definitions from the Meta class or method assignment to an object may not work for magical methods) :

 >>> class C: ... pass >>> c = C() >>> c.__len__ = lambda: 0 >>> len(c) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'C' has no len() 

For comparison, quack() can be directly assigned to the object itself:

 >>> c.quack = lambda: "ga ga" >>> quack(c) 'ga ga' 

But in order for len() work, it is necessary to place the definition in the class itself:

 >>> class C: ... def __len__(self): ... return 0 >>> len(C()) 0 

This is done to optimize the speed of calling such methods and to avoid the "metaclass confusion" described above by reference . In CPython, almost all special methods (a term for magic methods from a language specification) are stored in special slots in a type .

    look at this question like that

     def __repr__(self): return "({x})".format(x=self.x) class SomeClass:pass a = SomeClass() ax = 23 print(__repr__(a))