Python中getattr(),setattr(),delattr(),hasattr()使用注意事项

本文介绍了Python的几个内置函数。getattr()用于返回类、对象的属性或方法的值;setattr()可设置属性值,相当于添加类的变量;delattr()用于删除对象指定属性;hasattr()用于确定对象是否具有某个属性。还提及了各函数使用的一些注意事项。

Python中getattr,setattr,delattr,hasattr使用注意事项


本文参考:
https://blog.youkuaiyun.com/weixin_42233629/article/details/82261547
https://www.cnblogs.com/zhangjing0502/archive/2012/05/16/2503702.html

getattr()

getattr(object, name[, default])
getattr()用于返回一个类属性(classname.xx)、对象的属性(self.xx)或方法(def xx)的值。
个人理解等同于object.name的效果 第三个参数用于对应属性不存在时作为返回值返回
如下,获取属性或方法的前提是实现一个类,并实例该类

// define a class
class example(object:
	def __init__(self):
		self.user_name = 'li hua'
	def get_user_name(self):
		return self.user_name

my_instance = example()
print getattr(my_instance , 'user_name , 'not find') 
#如果my_instance 对象中有属性user_name 则打印self.user_name 的值,否则打印'not find'
print getattr(my_instance , 'method', 'default')   
#如果有方法method,否则打印其地址,否则打印default 

此处如果在getattr()后添加()则会在对象方法存在的情况下执行该方法

print getattr(my_instance , 'method', 'default')()   
#如果有方法method,运行函数并打印 None 否则打印default

同时getattr()用于返回类属性时,则无需实例该类

class Foo:
    School = 'xihu'
    Country = 'China'
    language = 'Chiness'

# 方法一,判断用户输入的内容是什么,并输出相关内容
inp = input('>>>')
if inp == 'School': print(Foo.School)  
elif inp == 'Country': print(Foo.Country)
elif inp == 'language': print(Foo.language)

# 条件语句每条都打印,非常麻烦,如果有很多条怎么办,用反射实现节省代码量,

# 方法二,用反射的方法
while True:
    inp = input('>>>')
    if hasattr(Foo, inp):  # 判断inp是否为Foo类的静态属性
        print(getattr(Foo, inp))  # 获取静态属性,并打印

返回类中的普通函数方法需要python3以上的版本
当类中进行__init__初始化后通过gettattr调用时注意需要传参数

class A:
    a = 'Laura'
    def __init__(self, name):
        self.name = name
    def common(self):
        print('in common')

print(getattr(A, 'a'))   # Laura # 为说明静态属性a可以直接打印,而方法common要加括号执行呢,因为在内存中a直接指向一个值,就是‘Laura’, 而common函数指向一个地址,加括号才可以触发该地址指向的内容执行。
getattr(A, 'common')(1)  # in common

同时getattr()可以返回模块或文件中的变量,但由于未做研究此处不作说明解释

setattr()

setattr(object, name, value)
setattr()用于设置一个属性值(字符串name),该值不一定是存在的。
setattr(x,“foobar”,123)相当于x.foobar = 123。
可以理解为添加类的变量

import sys

c = sys.modules['__main__']

class Foo:
    a = 'a'

	def func():
    	print('func')

Foo.s = 's'  # 通常的添加属性的方法

print(Foo.s)  # s

setattr(Foo, 'n', 'n')  # 用setattr设置一个属性为n,值为n的变量

print(Foo.n)  # n

setattr(Foo, 'n', 'w')  # 修改属性的值,所谓设置,就是有此变量时就更改,无此变量时就添加

print(Foo.n)  # 'w'

print(Foo.__dict__)  # {'__module__': '__main__', 'a': 'a', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 's': 's', 'n': 'w'}

print(c.__dict__)  # {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000146F37772B0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/学习资料/Daily Code and experience/day21 内置方法,反射,登录自动识别身份/反射反射反射.py', '__cached__': None, 'sys': <module 'sys' (built-in)>, 'c': <module '__main__' from 'D:/学习资料/Daily Code and experience/day21 内置方法,反射,登录自动识别身份/反射反射反射.py'>, 'Foo': <class '__main__.Foo'>, 'func': <function func at 0x00000146F372D1E0>}

delattr()

delattr(object, name)
与setattr()相对应的一组函数,参数是由一个对象(记住python中一切皆是对象)和一个字符串组成的。string参数必须是对象属性名之一。该函数删除该obj的一个由string指定的属性。delattr(x, ‘foobar’)=del x.foobar

# delattr()  删除变量

del Foo.Country

print(Foo.__dict__)

delattr(Foo, 'Country')  # 格式:(名称空间,‘要删除的变量名’)

delattr(Foo, 'func')

print(Foo.__dict__)

hasattr()

hasattr(object, name) -> bool
用于确定一个对象是否具有某个属性
在getattr()的代码举例中已经出现过。

<think>嗯,用户想了解Python中的callable和getattrsetattrdelattrhasattr这些函数的关系和用法。首先,我需要回忆这些函数各自的作用,然后看看它们之间有什么联系。先分开来看,hasattr用于检查对象是否有某个属性,setattr用来设置属性值,getattr获取属性值,delattr删除属性。而callable则是判断一个对象是否可以被调用,比如函数或类。这些函数都属于Python内置函数,用于动态处理对象的属性。 接下来,需要理清它们之间的关系。例如,当使用getattr获取一个属性时,如果该属性是一个方法(即可调用的),那么可以用callable来验证。或者,在动态调用方法前,先用hasattr检查是否存在,再用callable确认是否可执行。用户可能在实际开发中遇到动态处理对象属性的情况,比如根据输入的字符串调用不同的方法,这时候结合使用这些函数会很方便。比如,检查对象是否有某个方法(hasattr),确认方法存在后再判断是否可调用(callable),最后用getattr获取并执行。 还需要注意异常处理,比如使用delattr删除属性时,如果属性不存在会引发AttributeError,所以可能需要结合try-except块或者先用hasattr检查。此外,在动态设置属性时,setattr可以直接赋值,但如果属性名是变量,这会很有用。另外,引用中提到的一些情况,比如在__getattr__方法中避免无限循环,可能需要通过直接操作__dict__来实现。这点虽然和用户的问题没有直接关联,但如果在动态属性管理时涉及到这些魔术方法,需要注意。用户的问题可能还涉及到如何组合使用这些函数来实现动态行为。例如,在插件系统中动态加载模块的方法,或者根据配置调用不同的函数。这时候,hasattrgetattr配合使用,再加上callable检查,可以确保调用的有效性。 需要举例说明每个函数的用法,以及它们如何协同工作。比如,一个对象可能有多个方法,根据用户输入动态选择执行哪个方法。这时候,先用hasattr检查是否存在,再用getattr获取,callable判断是否可调用,最后调用。 另外,callable不仅可以用于方法,还可以用于其他可调用对象,比如类、lambda函数等。所以,在动态获取属性后,用callable确认是否可调用,可以增加代码的健壮性。可能还需要提到这些函数与__getattr__、__setattr__等魔术方法的关系,比如当使用getattr时,会触发对象的__getattr__方法,如果存在的话。但用户的问题可能更关注于内置函数使用,而不是魔术方法的覆盖。 最后,总结它们的关系:hasattr用于检查属性是否存在,getattr获取属性值,setattr设置,delattr删除,而callable则判断获取的属性是否可调用。这些函数共同支持了Python中动态属性管理的功能。</think>### Python动态属性管理与可调用对象检测 在Python中,`callable()`与`hasattr()`/`getattr()`/`setattr()`/`delattr()`共同构成动态属性管理的核心工具组,其关系与用法可通过以下结构化分析理解: --- #### 一、基础功能对比 1. **属性检测** `hasattr(obj, 'attr')`:判断对象是否包含指定属性(包括继承属性) ```python class Data: def __init__(self): self.value = 42 obj = Data() print(hasattr(obj, 'value')) # True ``` 2. **属性操作** - `getattr(obj, 'attr', default)`:获取属性值,支持默认值[^1] - `setattr(obj, 'attr', value)`:动态设置/修改属性[^1] - `delattr(obj, 'attr')`:删除属性(需配合异常处理)[^3] 3. **可调用性验证** `callable(obj.attr)`:判断属性是否为函数/方法/类等可调用对象 --- #### 二、组合应用场景 **案例:动态方法调用** ```python class Calculator: def add(self, a, b): return a + b calc = Calculator() method_name = 'add' if hasattr(calc, method_name): # 1.检测方法是否存在 func = getattr(calc, method_name) # 2.获取方法引用 if callable(func): # 3.验证可调用性 print(func(3, 5)) # 输出8 ``` **关键流程**: `存在性检测 → 属性获取 → 可调用性验证 → 执行调用` --- #### 三、特殊注意事项 1. **`delattr()`的异常处理** 删除不存在的属性会触发`AttributeError`,需配合`try-except`或前置`hasattr()`检查[^3]: ```python try: delattr(obj, 'non_existent_attr') except AttributeError as e: print(f"删除失败: {e}") ``` 2. **动态属性与`__dict__`的关系** 直接操作`obj.__dict__`可避免触发`__getattr__`/`__setattr__`的递归调用问题[^4] 3. **方法链式调用** `getattr()`可直接返回方法并立即调用: ```python getattr(calc, 'add')(3, 5) # 等效于calc.add(3,5) ``` --- #### 四、核心区别总结 | 函数 | 作用域 | 返回值类型 | 典型应用场景 | |---------------|----------------|-----------------|--------------------------| | `hasattr()` | 属性存在性检测 | 布尔值 | 动态功能开关控制 | | `getattr()` | 属性值获取 | 任意类型 | 插件系统/反射编程 | | `setattr()` | 属性赋值 | None | 运行时配置注入 | | `delattr()` | 属性删除 | None | 资源释放/状态重置 | | `callable()` | 可调用性验证 | 布尔值 | 安全执行回调函数 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值