赞
踩
hasattr()
函数用来判断某个类实例对象是否包含指定名称的属性或方法
hasattr(object, name)
obj
指的是某个类的实例对象name
表示指定的属性名或方法名返回值
class CLanguage:
age = 1
def __init__ (self):
self.name = "C语言中文网"
self.add = "123"
def say(self):
print("我正在学Python")
clangs = CLanguage()
print(hasattr(clangs,"age")) # True
print(hasattr(clangs,"name")) # True
print(hasattr(clangs,"add")) # True
print(hasattr(clangs,"say")) # True
print(hasattr(clangs,"out")) # False
True
True
True
True
False
显然,无论是属性名还是方法名,都在 hasattr()
函数的匹配范围内。因此,只能通过该函数判断实例对象是否包含该名称的属性或方法,但不能精确判断,该名称代表的是属性还是方法。
getattr()
函数获取某个类实例对象中指定属性的值。没错,和 hasattr() 函数不同,该函数只会从类对象包含的所有属性中进行查找。
getattr(obj, name[, default])
返回值
class CLanguage:
def __init__ (self):
self.name = "xiaoming"
self.add = "net"
def say(self):
print("我正在学Python")
clangs = CLanguage()
print(getattr(clangs,"name"))
print(getattr(clangs,"add"))
print(getattr(clangs,"say"))
print(getattr(clangs,"display",'nodisplay'))
xiaoming
net
<bound method CLanguage.say of <__main__.CLanguage object at 0x00000209F0511490>>
nodisplay
既然 getattr(clangs,'name')
和 clangs.name
都能获取 clangs
对象的 name
属性的值,那使用后者不就行了吗?毕竟点语法看起来比 getattr
函数简单多了,不用写那么多字。确实,一般情况下,使用点语法来获取属性值非常方便。但是也存在一些场景,点语法无能为力,只好使用 getattr
函数来获取属性值。
究竟应该使用谁,关键就在于,编写代码的时候程序员是否能够确定要获取哪个属性的值。
如果明确地知道,就是想要获取 age
这个属性的值,那么 clangs.name
就满足了我的需求。但是,试想如下的场景:
clangs 对象有 name,age,job,weight,height 五个属性,要根据用户的选择来展示相应的属性。也就是说,用户告诉程序“给我看看 clangs 的身高吧!”,程序就要把 height 属性的值展示给用户看。
上面这个场景中,程序员写代码的时候无法确定要访问哪个属性值,选择权是交给用户的。而用户的输入是一个字符串 “height”,字符串在 clangs .height 这样的点语法里并没有容身之处。怎么样?这个需求用点语法不太合适了吧?(如果非要用点语法,也不是不可以。比如,用一个字典把 clangs 所有的属性值都存起来。键就是 “height” 这样的字符串,值就是 clangs.height 这样的属性值。那么,就可以用 “height" 这样的字符串把对应的属性值取出来了。不过这个方法没有接下来要说到的 getattr 好。)这时候,用 getattr 就非常合适了。因为,getattr 的第二个参数类型正是字符串!可以用 getattr(clangs,“height”) 来取出身高的值。甚至还可以使用default参数很好地解决用户输入的属性不存在的问题。
from typing import NamedTuple class CLanguage(NamedTuple): '''人类''' name: str age: int job: str weight: float height: float clangs = CLanguage('clangs', 32, 'actor', 60, 178) # 把用户输入的字符串赋值给变量attribute_name attribute_name = input('''What do you want to know about clangs? Enter an attribute name>>>''') # 注意,上述字符串被传进了这个函数作为第二个参数 # 第三个参数是属性不存在时返回的字符串 print(getattr(clangs , attribute_name, 'Sorry, this attribute does not exist.'))
getattr(obj,"_attr")
getattr(obj,"_" + attr)
_attr
属性,而第二种可以访问所有带下划线的属性class Student: # 定义类
def __init__(self,name,identity,age):
self._name = name
self._identity = identity
self.age = age
def __getitem__(self,item):
if isinstance(item,str):
return getattr(self,"_item")
st=Student("Huang Lei",1323010212,12) # 实例化
print(st["age"])
AttributeError: 'Student' object has no attribute '_item'
print(st["name"])
AttributeError: 'Student' object has no attribute '_item'
上面方式只能访问 '_item'
属性。不论是否是带下划线的属性。
class Student:
def __init__(self,name,identity,age):
self._name = name
self._identity = identity
self.age = age
def __getitem__(self,item):
if isinstance(item,str):
return getattr(self,"_" + item)
st=Student("Huang Lei",1323010212,12)
print(st["age"])
AttributeError: 'Student' object has no attribute '_age'
print(st["name"])
Huang Lei
setattr()
函数的功能相对比较复杂,它最基础的功能是修改类实例对象中的属性值。其次,它还可以实现为实例对象动态添加属性或者方法。
setattr(obj, name, value)
class CLanguage:
def __init__ (self):
self.name = "xiaoming"
self.add = "net"
def say(self):
print("我正在学Python")
clangs = CLanguage()
print(clangs.name)
print(clangs.add)
setattr(clangs, "name", "Python教程")
setattr(clangs, "add", "python")
print(clangs.name)
print(clangs.add)
xiaoming
net
Python教程
python
利用 setattr() 函数,还可以将类属性修改为一个类方法,同样也可以将类方法修改成一个类属性
def say(self):
print("我正在学Python")
class CLanguage:
def __init__ (self):
self.name = "xiaoming"
self.add = "net"
clangs = CLanguage()
print(clangs.name)
print(clangs.add)
setattr(clangs, "name", say)
clangs.name(clangs)
xiaoming
net
我正在学Python
显然,通过修改 name 属性的值为 say(这是一个外部定义的函数),原来的 name 属性就变成了一个 name() 方法。
使用 setattr() 函数对实例对象中执行名称的属性或方法进行修改时,如果该名称查找失败,Python 解释器不会报错,而是会给该实例对象动态添加一个指定名称的属性或方法
def say(self):
print("我正在学Python")
class CLanguage:
pass
clangs = CLanguage()
setattr(clangs, "name", "xiaoming")
setattr(clangs, "say", say)
print(clangs.name)
clangs.say(clangs)
xiaoming
我正在学Python
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。