Is there anything static about python function / method calls?

In asking a question about reflection I asked:

Good answer. But there is a difference between the words myobject.foo()and x = getattr(myobject, "foo"); x();. Even if it is only cosmetic. In the first, foo () is compiled statically. In the second case, a string can be produced in any number of ways. - Joe 1 hour ago

What answer did you get:

Eh, potato / solanum tuberosum ... in python, niether is statically compiled, so they are more or less equivalent. - SWeko 1 hour ago

I know that the elements of Python objects are stored in a dictionary and that everything is dynamic, but I assumed that given the following code:

class Thing():
  def m(self):
    pass

t = Thing()

The following code will somehow be statically compiled when creating .pyc:

t.m()

. m(), . .

:

meth = getattr(t, "m")
meth()

? ?

+3
5

, , dis.dis.

, LOAD_ATTR . , " TOS [top of stack] getattr(TOS, co_names[namei])".

>>> from dis import dis
>>> dis(lambda: t.m())
  1           0 LOAD_GLOBAL              0 (t)
              3 LOAD_ATTR                1 (m)
              6 CALL_FUNCTION            0
              9 RETURN_VALUE        
>>> dis(lambda: getattr(t, 'm')())
  1           0 LOAD_GLOBAL              0 (getattr)
              3 LOAD_GLOBAL              1 (t)
              6 LOAD_CONST               0 ('m')
              9 CALL_FUNCTION            2
             12 CALL_FUNCTION            0
             15 RETURN_VALUE        
+7

(, python, , - , , , ).

python . :

t = Thing()
t.m = lambda : 1
t.m()
+3

, Python , CPython.

, , , - . Python , CPython .

, t.m() , getattr(), , getattr(): getattr() .

+2

( HS); class "" :

. , . , . classs (. ), . ( , .) , , . [4] . .

( Python 7.7 Link: Class Definitions )

In other words, during startup, the interpreter executes the code inside the block classand saves the resulting context. There is no way at compile time to find out what the class will look like.

+1
source

With the help of, getattryou can access attributes whose names are not valid identifiers, although I'm not sure that a use case is used to use such attributes, and not to use a dictionary.

>>> setattr(t, '3', lambda : 4)
>>> t.3()
  File "<stdin>", line 1
    t.3()
      ^
SyntaxError: invalid syntax
>>> getattr(t, '3')()
4
+1
source

Source: https://habr.com/ru/post/1786662/


All Articles