getattr 方法解析
Erstellt am: 18. Januar 2025
Erstellt am: 18. Januar 2025
Analyzing function bindings
OK, let me see. The method run
is bound to the Demo
class, showing it's a function object but not tied to any instance. In Python 3, it's just a function, not an unbound method like in Python 2.
Examining method bindings
OK, let's break this down: bb
is a bound method from the Demo
class instance, with self
set. Calling cc
uses Demo.run
with mismatched arguments, producing a functioning but incorrect output.
Analyzing bound and unbound methods
OK, let me see: bound methods effectively use self
from the instance, while unbound methods are invoked without an instance, leading to different handling of arguments and output formatting.
Thought about Python getattr usage,持续 8 秒
下面我们逐行分析下这段代码做了什么,以及打印出来的结果分别代表了哪些含义。示例代码如下(做了些简化):
class Demo(object): def run(self, name, age): return f"My name is {name}, age is {age}!" aa = getattr(Demo, 'run') print(aa) bb = getattr(Demo(), 'run') print(bb) cc = getattr(Demo, 'run')(1, "dgw", "26") print(cc) dd = getattr(Demo(), 'run')("dgw", "26") print(dd)
aa = getattr(Demo, 'run')
Demo.run
在 Python 3 中是一个「函数对象」(可以理解为没有绑定实例的函数),在 Python 2 里会显示为 unbound method,但在 Python 3 里仅仅是一个 function。aa
相当于拿到了 Demo
类里定义的 run
这个函数本身,但它没有和任何具体的实例绑定。print(aa)
输出时,通常会看到类似:
这说明它是一个函数对象。<function Demo.run at 0x7f1234567890>
bb = getattr(Demo(), 'run')
Demo()
先生成了一个 Demo
的实例。getattr(Demo(), 'run')
则相当于从实例上获取 run
方法。self
的方法,称为 bound method。bb
会是一个「绑定到 Demo()
这个对象」的函数引用。print(bb)
时会看到类似:
这说明它是绑定到某个具体对象的可调用方法。<bound method Demo.run of <__main__.Demo object at 0x7f1234567890>>
cc = getattr(Demo, 'run')(1, "dgw", "26")
getattr(Demo, 'run')
和第 1 步一样,得到的仍然是类上的函数对象(没有绑定实例)。(1, "dgw", "26")
。def run(self, name, age): ...
的本质,是 run
函数的第一个参数要接收实例对象(即 self
)。如果我们直接通过类拿到函数本身来调用,那么需要手动去提供 self
。self = 1
name = "dgw"
age = "26"
self
来操作属性(也没做其它类型检查),所以这个“1”作为 self
不会触发报错,依然可以正常返回字符串——只要里面不引用 self
的其他方法/属性就行。"My name is dgw, age is 26!"
dd = getattr(Demo(), 'run')("dgw", "26")
Demo()
生成一个 Demo
实例;getattr(Demo(), 'run')
相当于拿到这个实例已经绑定好的 run
方法(就跟上面 bb
一样)。self
以外的参数即可:
name = "dgw"
age = "26"
"My name is dgw, age is 26!"
aa = getattr(Demo, 'run')
aa
只是一个函数引用。bb = getattr(Demo(), 'run')
cc = getattr(Demo, 'run')(1, "dgw", "26")
(self, name, age)
。虽然看起来怪异,但因为函数内部没用 self
做特殊操作,所以不会报错,返回相同的字符串。dd = getattr(Demo(), 'run')("dgw", "26")
name
和 age
就可以调用,返回"My name is dgw, age is 26!"
。这样就能清晰区分为什么会有“unbound function(或function)” 和 “bound method” 的区别,以及传参为什么会不一样。