How can I explicitly see what self does in python?

2024/9/21 5:45:56

I've read somewhere that the use of ‘self’ in Python converts myobject.method (arg1, arg2) into MyClass.method(myobject, arg1, arg2).

Does anyone know how I can prove this? Is it only possible if I look at the bytecode by using dis.dis?

Answer

self doesn't do anything. self is merely the conventional name given to the first argument of a method in Python class definitions. This argument will be passed an instance of the class.

Essentially, to understand what is actually going on, you have to understand Python descriptors. The best places are the official docs To boil it down, descriptor objects are objects that implement __get__, __set__ or __delete__. These methods intercept object attribute access, obj.x, object attribute assignment: obj.x = 42, and object attribute deletion, del obj.x.

Also, check out the HOWTO, where they show how Python functions and methods are simply descriptors, and show an example Python implementation (of course, in CPython, this is implemented in C):

class Function(object):. . .def __get__(self, obj, objtype=None):"Simulate func_descr_get() in Objects/funcobject.c"if obj is None:return selfreturn types.MethodType(self, obj)

We can "cheat" and create our own object that merely wraps a function object, and see that this works.

import types
class Function:def __init__(self, func):self._func = funcdef __call__(self, *args, **kwargs):return self._func(*args, **kwargs)def __get__(self, obj, objtype=None):"Simulate func_descr_get() in Objects/funcobject.c https://docs.python.org/3/howto/descriptor.html#functions-and-methods"if obj is None:return selfelse:return types.MethodType(self, obj)class Foo:def __init__(self):self.foo = 42bar = Function(lambda self:self.foo ** 2

And or, in a REPL:

>>> import types
>>>
>>> class Function:
...     def __init__(self, func):
...         self._func = func
...     def __call__(self, *args, **kwargs):
...         return self._func(*args, **kwargs)
...     def __get__(self, obj, objtype=None):
...         "Simulate func_descr_get() in Objects/funcobject.c https://docs.python.org/3/howto/descriptor.html#functions-and-methods"
...         if obj is None:
...             return self
...         else:
...             return types.MethodType(self, obj)
...
>>> class Foo:
...    def __init__(self):
...        self.foo = 42
...    bar = Function(lambda self:
...        self.foo ** 2
...    )
...
>>> Foo().bar()
1764

This shows you that the magic behind "self" is merely that function objects are descriptors, they implement a __get__ method which either returns the function itself if called without an instance, or returns a method-object that binds the first argument.

https://en.xdnf.cn/q/119237.html

Related Q&A

Recieve global variable (Cython)

I am using Cython in jupyter notebook. As I know, Cython compiles def functions.But when I want to call function with global variable it doesnt see it. Are there any method to call function with variab…

Counting elements in specified column of a .csv file

I am programming in Python I want to count how many times each word appears in a column. Coulmn 4 of my .csv file contains cca. 7 different words and need to know how many times each one appears. Eg. t…

Why does genexp(generator expression) is called genexp? not iterexp?

A generator is a special kind of iterator, and it has some methods that an normal iterator doesnt have such as send(), close()... etc. One can get a generator by using a genexp like below:g=(i for i in…

why does no picture show

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg if __name__ == "__main__":fig1 = ...print("start plotting")canvas = FigureCanvasQTAgg(fig1)canvas.draw()canvas.show(…

How Normalize Data Mining Min Max from Mysql in Python

This is example of my data in mysql, I use lib flashext.mysql and python 3RT NK NB SU SK P TNI IK IB TARGET 84876 902 1192 2098 3623 169 39 133 1063 94095 79194 …

complex json file to csv in python

I need to convert a complex json file to csv using python, I tried a lot of codes without success, I came here for help,I updated the question, the JSON file is about a million,I need to convert them t…

python pygame - how to create a drag and drop with multiple images?

So Ive been trying to create a jigsaw puzzle using pygame in python.The only problem is that Im having trouble creating the board with multiple images that i can drag along the screen (no need to conne…

Efficiently append an element to each of the lists in a large numpy array

I have a really large numpy of array of lists, and I want to append an element to each of the arrays. I want to avoid using a loop for the sake of performance. The following syntax is not working. a=np…

How to traverse a high-order range in Python? [duplicate]

This question already has answers here:Equivalent Nested Loop Structure with Itertools(2 answers)Closed 4 years ago.In python, we can use range(x) to traverse from 0 to x-1. But what if I want to trave…

How to send eth_requestAccounts to Metamask in PyScript?

I am trying to get address from installed MetaMask on the browser. We used to do this in JS as follow:const T1 = async () => {let Address = await window.ethereum.request({method: "eth_requestAc…