从 getattr() 访问对象方法
Access object methods from getattr()
我需要创建一个脚本,允许您从 getattr()
内置函数动态访问对象属性,但是在尝试访问对象方法时我遇到了很多麻烦,这里是一个示例:
class Dog():
def __init__(self):
self.age = 12
self.name = 'Bobby'
def eat(self):
print("I'm eating!")
如果我随后初始化对象并尝试访问它们的属性:
mydog = Dog()
res = getattr(mydog, 'age')
print(res)
#--> return: 12
但是如果我尝试访问 eat
方法:
mydog = Dog()
res = getattr(mydog, 'eat()')
print(res)
#--> return: AttributeError: 'Dog' object has no attribute 'eat()'
我已经尝试过写不带引号的方法名,我找到的最好的解决办法是写不带括号的方法,然后从 res
:
访问函数
mydog = Dog()
res = getattr(mydog, 'eat')
res()
#--> return: I'm eating!
我可以编写一个条件语句来检测 res
是否包含变量或函数并调用它以防它是一个方法,但是有更好的解决方案吗?
使用一个小的单行条件来为你检测它是不错的,而且使用 callable
:
很短
attr = getattr(mydog, attr_name)
res = attr() if callable(attr) else attr
在Python3.8,你甚至可以一行:
res = attr() if callable(attr := getattr(mydog, attr_name)) else attr
在方法 eat
上使用 @property
装饰器,它将成功,这样我们就可以毫无问题地检索它 getattr
:
class Dog():
def __init__(self):
self.age = 12
self.name = 'Bobby'
@property
def eat(self):
return "I'm eating!"
mydog = Dog()
res1 = getattr(mydog, 'age')
res2 = getattr(mydog, 'name')
res3 = getattr(mydog, 'eat')
print(res1) #Output: 12
print(res2) #Output: Bobby
print(res3) #Output: I'm eating!
如果我们不将 eat
变成 属性,那么调用 getattr(mydog, "eat")
将 return 引用该方法而不调用它。但是,当您在方法中设置 @property
时,将创建 eat
的 getter
,当您尝试调用该属性时将调用它。
如果我们想扩展上面的内容,以便我们可以更改 eat
的值,那么我们还可以创建一个 setter
的 eat:
class Dog():
def __init__(self):
self._eat = "I'm eating!"
@property
def eat(self):
return self._eat
@eat.setter
def eat(self, eat_string):
self._eat = eat_string
mydog = Dog()
print(mydog.eat) #Output: I'm eating!
mydog.eat = "Stop bothering me!"
print(mydog.eat) #Output: Stop bothering me!
我需要创建一个脚本,允许您从 getattr()
内置函数动态访问对象属性,但是在尝试访问对象方法时我遇到了很多麻烦,这里是一个示例:
class Dog():
def __init__(self):
self.age = 12
self.name = 'Bobby'
def eat(self):
print("I'm eating!")
如果我随后初始化对象并尝试访问它们的属性:
mydog = Dog()
res = getattr(mydog, 'age')
print(res)
#--> return: 12
但是如果我尝试访问 eat
方法:
mydog = Dog()
res = getattr(mydog, 'eat()')
print(res)
#--> return: AttributeError: 'Dog' object has no attribute 'eat()'
我已经尝试过写不带引号的方法名,我找到的最好的解决办法是写不带括号的方法,然后从 res
:
mydog = Dog()
res = getattr(mydog, 'eat')
res()
#--> return: I'm eating!
我可以编写一个条件语句来检测 res
是否包含变量或函数并调用它以防它是一个方法,但是有更好的解决方案吗?
使用一个小的单行条件来为你检测它是不错的,而且使用 callable
:
attr = getattr(mydog, attr_name)
res = attr() if callable(attr) else attr
在Python3.8,你甚至可以一行:
res = attr() if callable(attr := getattr(mydog, attr_name)) else attr
在方法 eat
上使用 @property
装饰器,它将成功,这样我们就可以毫无问题地检索它 getattr
:
class Dog():
def __init__(self):
self.age = 12
self.name = 'Bobby'
@property
def eat(self):
return "I'm eating!"
mydog = Dog()
res1 = getattr(mydog, 'age')
res2 = getattr(mydog, 'name')
res3 = getattr(mydog, 'eat')
print(res1) #Output: 12
print(res2) #Output: Bobby
print(res3) #Output: I'm eating!
如果我们不将 eat
变成 属性,那么调用 getattr(mydog, "eat")
将 return 引用该方法而不调用它。但是,当您在方法中设置 @property
时,将创建 eat
的 getter
,当您尝试调用该属性时将调用它。
如果我们想扩展上面的内容,以便我们可以更改 eat
的值,那么我们还可以创建一个 setter
的 eat:
class Dog():
def __init__(self):
self._eat = "I'm eating!"
@property
def eat(self):
return self._eat
@eat.setter
def eat(self, eat_string):
self._eat = eat_string
mydog = Dog()
print(mydog.eat) #Output: I'm eating!
mydog.eat = "Stop bothering me!"
print(mydog.eat) #Output: Stop bothering me!