1. getattr基本语法
getattr()
是 Python 内置的一个函数,可以用来获取一个对象的属性值或方法。其基本语法为:
getattr(object, name[, default])
其中,object 是要获取属性值或方法的对象;name 是要获取的属性名或方法名;default 是可选参数,当指定的属性或方法不存在时,会返回 default 的值。
2. 基本用法
getattr()
可以通过对象实例或类名来获取属性值或方法,也可以获取内置函数、内置类型和标准库中的属性和方法。
下面是一些常见的使用 getattr()
的案例:
2.1 获取对象的属性值
class MyClass:
def __init__(self):
self.x = 1
self.y = 2
obj = MyClass()
print(getattr(obj, 'x')) # 输出 1
print(getattr(obj, 'y')) # 输出 2
2.2 获取对象的方法
class MyClass:
def my_method(self):
print('Hello, world!')
obj = MyClass()
method = getattr(obj, 'my_method')
method() # 输出 "Hello, world!"
2.3 获取内置函数和类型
func = getattr(__builtins__, 'abs')
print(func(-1)) # 输出 1
type_name = 'str'
type_obj = getattr(__builtins__, type_name)
print(type_obj('Hello, world!')) # 输出 "Hello, world!"
2.4 获取标准库中的属性和方法
import datetime
now = datetime.datetime.now()
attr_name = 'year'
attr_value = getattr(now, attr_name)
print(attr_value) # 输出当前年份
method_name = 'strftime'
method_args = ['%Y-%m-%d %H:%M:%S']
method = getattr(now, method_name)
formatted = method(*method_args)
print(formatted) # 输出格式化后的时间字符串,如 "2023-05-06 10:30:00"
在实际开发中,getattr()
还可以用于实现动态调用函数或方法的功能,以及在需要处理大量类似属性或方法的代码时,简化代码的编写。
3. 开源代码的实际使用
getattr()
还可以结合 import_module()
函数,实现动态执行某个文件中某个类的方法的功能。这一点在 Uvicorn [2]的代码 importer.py 中得到了应用,用于对应用程序的加载,具体的代码如下:
import importlib
from typing import Any
class ImportFromStringError(Exception):
pass
def import_from_string(import_str: Any) -> Any:
if not isinstance(import_str, str):
return import_str
module_str, _, attrs_str = import_str.partition(":")
if not module_str or not attrs_str:
message = 'Import string "{import_str}" must be in format "<module>:<attribute>".'
raise ImportFromStringError(message.format(import_str=import_str))
try:
module = importlib.import_module(module_str)
except ModuleNotFoundError as exc:
if exc.name != module_str:
raise exc from None
message = 'Could not import module "{module_str}".'
raise ImportFromStringError(message.format(module_str=module_str))
instance = module
try:
for attr_str in attrs_str.split("."):
instance = getattr(instance, attr_str)
except AttributeError:
message = 'Attribute "{attrs_str}" not found in module "{module_str}".'
raise ImportFromStringError(message.format(attrs_str=attrs_str, module_str=module_str))
return instance
那么上面的方法怎么使用呢?写一个最简单的加法和减法计算的模块,并命名为 module_a.py,该模块代码如下:
def add(a:int, b:int):
return a+b
def minus(a:int, b:int):
return a-b
调用处的代码如下:
from importer import import_from_string
# 加载模块并找到属性,模块为module_a,属性为add
app_add = import_from_string('module_a:add')
app_minus = import_from_string('module_a:minus')
print(app_add(1, 2)) # 3
print(app_minus(3, 1)) # 2
这样,就实现了动态的模块加载
参考文献
[1] https://www.runoob.com/python/python-func-getattr.html
[2] https://github.com/encode/uvicorn