python - 究竟是什么getattr()以及如何使用它?

我正在阅读有关getattr()功能的信息。 问题是我仍然无法掌握它的用法。 我唯一理解getattr()是getattr(li, "pop")与调用li.pop相同。

我不明白这本书何时提到你如何使用它来获取函数的引用而不知道它的名字直到运行时。 也许这就是我在编程方面的一般菜鸟。 任何人都可以对这个问题有所了解吗? 我何时以及如何使用它?

10个解决方案

236 votes

Python中的对象可以具有属性(实际上,每个对象都具有内置属性 - 数据属性和方法(函数是值,即对象)也可以使用这些属性)。

例如,您有一个对象test,它有几个属性:person.gender,person.the_method()等。

您可以通过以下方式访问这些属性(无论是方法还是数据对象):test,person.gender,person.the_method()等。

但是如果你在编写程序时不知道属性的名称怎么办? 例如,您将属性的名称存储在名为test的变量中。

如果

attr_name = 'gender'

然后,而不是写作

gender = person.gender

你可以写

gender = getattr(person, attr_name)

一些做法:

Python 3.4.0 (default, Apr 11 2014, 13:05:11)

>>> class Person():

... name = 'Victor'

... def say(self, what):

... print(self.name, what)

...

>>> getattr(Person, 'name')

'Victor'

>>> attr_name = 'name'

>>> person = Person()

>>> getattr(person, attr_name)

'Victor'

>>> getattr(person, 'say')('Hello')

Victor Hello

test将引发test如果对象中不存在具有给定名称的属性:

>>> getattr(person, 'age')

Traceback (most recent call last):

File "", line 1, in

AttributeError: 'Person' object has no attribute 'age'

但是你可以传递一个默认值作为第三个参数,如果这个属性不存在,它将被返回:

>>> getattr(person, 'age', 0)

0

您可以使用test以及test迭代所有属性名称并获取其值:

>>> dir(1000)

['__abs__', '__add__', ..., '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

>>> obj = 1000

>>> for attr_name in dir(obj):

... attr_value = getattr(obj, attr_name)

... print(attr_name, attr_value, callable(attr_value))

...

__abs__ True

...

bit_length True

...

>>> getattr(1000, 'bit_length')()

10

这样做的一个实际用途是找到名称以test开头并调用它们的所有方法。

与setattr类似,有setattr,它允许您设置具有其名称的对象的属性:

>>> setattr(person, 'name', 'Andrew')

>>> person.name # accessing instance attribute

'Andrew'

>>> Person.name # accessing class attribute

'Victor'

>>>

warvariuc answered 2019-03-04T05:36:33Z

78 votes

对我来说,getattr最容易解释这种方式:

它允许您根据字符串的内容调用方法,而不是键入方法名称。

例如,你不能这样做:

obj = MyObject()

for x in ['foo', 'bar']:

obj.x()

因为x不是“builtin”类型,而是“str”类型。 但是,你可以这样做:

obj = MyObject()

for x in ['foo', 'bar']:

getattr(obj, x)()

它允许您根据输入动态连接对象。 我发现它在处理自定义对象和模块时很有用。

NuclearPeon answered 2019-03-04T05:37:33Z

58 votes

您可以在此处查看完整示例:

[https://linux.die.net/diveintopython/html/power_of_introspection/index.html]

内省可以用于不同的目的,“Dive Into Python”中提供的内容只是一种在应用程序中动态添加功能(插件)的方法。

通过动态我的意思是不在核心应用程序中进行修改以添加新功能。

以'Dive Into Python'为例 - 一个从不同文件的文件中提取属性的简单应用程序 - 您可以添加新文件格式的处理,而无需修改原始应用程序。

我建议你完成这本书。 当你阅读时,一切都会变得越来越清晰。

Alois Cochard answered 2019-03-04T05:34:39Z

43 votes

getattr的一个非常常见的用例是将数据映射到函数。

例如,在像Django或Pylons这样的Web框架中,getattr可以直接将Web请求的URL映射到将要处理它的函数。 例如,如果你看看Pylons的路由引擎,你会看到(默认情况下,至少)它会删除一个请求的URL,例如:

http://www.example.com/customers/list

进入“客户”和“列表”。 然后它搜索名为getattr的控制器类。假设它找到该类,它将创建该类的实例,然后使用getattr获取其list方法。 然后它调用该方法,将请求作为参数传递给它。

一旦掌握了这个想法,扩展Web应用程序的功能变得非常容易:只需向控制器类添加新方法,然后在页面中创建使用这些方法的相应URL的链接。 所有这一切都可以通过getattr实现。

Robert Rossney answered 2019-03-04T05:38:24Z

12 votes

下面是一个快速而又脏的示例,说明类如何根据使用getattr()执行的操作系统来触发不同版本的save方法。

import os

class Log(object):

def __init__(self):

self.os = os.name

def __getattr__(self, name):

""" look for a 'save' attribute, or just

return whatever attribute was specified """

if name == 'save':

try:

# try to dynamically return a save

# method appropriate for the user's system

return getattr(self, self.os)

except:

# bail and try to return

# a default save method

return getattr(self, '_save')

else:

return getattr(self, name)

# each of these methods could have save logic specific to

# the system on which the script is executed

def posix(self): print 'saving on a posix machine'

def nt(self): print 'saving on an nt machine'

def os2(self): print 'saving on an os2 machine'

def ce(self): print 'saving on a ce machine'

def java(self): print 'saving on a java machine'

def riscos(self): print 'saving on a riscos machine'

def _save(self): print 'saving on an unknown operating system'

def which_os(self): print os.name

现在让我们在一个例子中使用这个类:

logger = Log()

# Now you can do one of two things:

save_func = logger.save

# and execute it, or pass it along

# somewhere else as 1st class:

save_func()

# or you can just call it directly:

logger.save()

# other attributes will hit the else

# statement and still work as expected

logger.which_os()

Josh answered 2019-03-04T05:38:59Z

6 votes

除了这里所有令人惊叹的答案之外,还有一种方法可以使用getattr来保存大量代码并使其保持紧密。 这个想法是在代码的可怕代表之后发生的,而代码有时可能是必要的。

脚本

假设您的目录结构如下:

- superheroes.py

- properties.py

并且,您可以在superheroes.py中获取有关getattr,Iron Man,Doctor Strange的信息的功能。您可以在properties.py的紧凑型dict中非常巧妙地写下所有这些属性,然后访问它们。

getattr

thor = {

'about': 'Asgardian god of thunder',

'weapon': 'Mjolnir',

'powers': ['invulnerability', 'keen senses', 'vortex breath'], # and many more

}

iron_man = {

'about': 'A wealthy American business magnate, playboy, and ingenious scientist',

'weapon': 'Armor',

'powers': ['intellect', 'armor suit', 'interface with wireless connections', 'money'],

}

doctor_strange = {

'about': ' primary protector of Earth against magical and mystical threats',

'weapon': 'Magic',

'powers': ['magic', 'intellect', 'martial arts'],

}

现在,假设您希望在getattr中按需返回每个功能。因此,有类似的功能

from .properties import thor, iron_man, doctor_strange

def get_thor_weapon():

return thor['weapon']

def get_iron_man_bio():

return iron_man['about']

def get_thor_powers():

return thor['powers']

...以及更多基于键和超级英雄返回不同值的函数。

在getattr的帮助下,您可以执行以下操作:

from . import properties

def get_superhero_weapon(hero):

superhero = getattr(properties, hero)

return superhero['weapon']

def get_superhero_powers(hero):

superhero = getattr(properties, hero)

return superhero['powers']

您大大减少了代码行数,功能和重复次数!

哦,当然,如果你有变量这样的坏名字,如getattr,它们可以通过简单的方式制作和访问

def get_superhero_weapon(hero):

superhero = 'properties_of_{}'.format(hero)

all_properties = getattr(properties, superhero)

return all_properties['weapon']

注意:对于这个特殊的问题,可以有更聪明的方法来处理这种情况,但我们的想法是提供一个洞察力,在正确的位置使用getattr来编写更干净的代码。

unixia answered 2019-03-04T05:40:35Z

3 votes

我有时会使用n_calls_to_plot在代码中使用它们之前懒洋洋地初始化次要重要性的属性。

比较以下内容:

class Graph(object):

def __init__(self):

self.n_calls_to_plot = 0

#...

#A lot of code here

#...

def plot(self):

self.n_calls_to_plot += 1

对此:

class Graph(object):

def plot(self):

self.n_calls_to_plot = 1 + getattr(self, "n_calls_to_plot", 0)

第二种方式的优点是n_calls_to_plot仅出现在使用它的代码中的位置周围。 这对于可读性是有好处的,因为(1)你可以在阅读它的使用方式时立即看到它的起始值,(2)它不会引起对__init__(..)方法的干扰,理想情况下应该是关于概念状态的 class,而不是由于技术原因(例如优化)仅由函数的某个方法使用的某个实用程序计数器,并且与对象的含义无关。

Evgeni Sergeev answered 2019-03-04T05:41:23Z

3 votes

当我从存储在类中的数据创建XML文件时,如果属性不存在或类型为getattr,则经常会收到错误。在这种情况下,我的问题是不知道属性名称是什么, 如您的问题所述,而是数据存储在该属性中。

class Pet:

def __init__(self):

self.hair = None

self.color = None

如果我使用getattr执行此操作,即使属性值为set,它也将返回getattr,这将导致我的ElementTree set命令失败。

hasattr(temp, 'hair')

>>True

如果属性值的类型为getattr,getattr也会返回它,这将导致我的ElementTree set命令失败。

c = getattr(temp, 'hair')

type(c)

>> NoneType

我现在使用以下方法来处理这些情况:

def getRealAttr(class_obj, class_attr, default = ''):

temp = getattr(class_obj, class_attr, default)

if temp is None:

temp = default

elif type(temp) != str:

temp = str(temp)

return temp

这是我何时以及如何使用getattr。

btathalon answered 2019-03-04T05:42:24Z

2 votes

# getattr

class hithere():

def french(self):

print 'bonjour'

def english(self):

print 'hello'

def german(self):

print 'hallo'

def czech(self):

print 'ahoj'

def noidea(self):

print 'unknown language'

def dispatch(language):

try:

getattr(hithere(),language)()

except:

getattr(hithere(),'noidea')()

# note, do better error handling than this

dispatch('french')

dispatch('english')

dispatch('german')

dispatch('czech')

dispatch('spanish')

Kduyehj answered 2019-03-04T05:42:49Z

2 votes

getattr()在Python中实现switch语句的另一个用途。 它使用两种反射来获取案例类型。

import sys

class SwitchStatement(object):

""" a class to implement switch statement and a way to show how to use gettattr in Pythion"""

def case_1(self):

return "value for case_1"

def case_2(self):

return "value for case_2"

def case_3(self):

return "value for case_3"

def case_4(self):

return "value for case_4"

def case_value(self, case_type=1):

"""This is the main dispatchmethod, that uses gettattr"""

case_method = 'case_' + str(case_type)

# fetch the relevant method name

# Get the method from 'self'. Default to a lambda.

method = getattr(self, case_method, lambda: "Invalid case type")

# Call the method as we return it

return method()

def main(_):

switch = SwitchStatement()

print swtich.case_value(_)

if __name__ == '__main__':

main(int(sys.argv[1]))

Jules Damji answered 2019-03-04T05:43:20Z

python中的getattr的用法_python - 究竟是什么getattr()以及如何使用它?相关推荐

  1. python中pop函数的用法_python中pop()函数怎么用

    python中pop()函数的用法:pop()函数用于移除列表中的一个元素(默认最后一个元素),并且返回从列表中移除的元素对象.函数语法:[list.pop(ojb=list[-1])]. pop() ...

  2. python中divmod函数的用法_Python中divmod函数的用法

    Python中divmod函数的用法,语言,余数,是一种,面向对象,函数 Python中divmod函数的用法 Python中divmod函数的用法 在Python中divmod函数的作用是把除数和余 ...

  3. [转载] python中string函数的用法_python中string模块各属性以及函数的用法

    参考链接: Python中的string.octdigits 任何语言都离不开字符,那就会涉及对字符的操作,尤其是脚本语言更是频繁,不管是生产环境还是面试考验都要面对字符串的操作. python的字符 ...

  4. python中if else语句用法_python中if及if-else如何使用

    if 结构 if 结构允许程序做出选择,并根据不同的情况执行不同的操作 基本用法 比较运算符 根据 PEP 8 标准,比较运算符两侧应该各有一个空格,比如:5 == 3. PEP8 标准 ==(相等) ...

  5. python中insert()函数的用法_Python list insert()用法及代码示例

    insert()是Python中的内置函数,可将给定元素插入列表中的给定索引. 用法: list_name.insert(index, element) 参数: index - the index a ...

  6. python中all函数的用法_python中map、any、all函数用法分析

    这篇文章主要介绍了 python 中 map . any . all 函数用法 , 实例分析了 map . any . all 函数 的相关使用技巧 , 具有一定参考借鉴价值 , 需要的朋友可以参考下 ...

  7. python中shutil.copyfile的用法_Python shutil.copyfile()用法及代码示例

    Python中的Shutil模块提供了许多对文件和文件集合进行高级操作的功能.它属于Python的标准实用程序模块.此模块有助于自动执行文件和目录的复制和删除过程. shutil.copyfile() ...

  8. python中字符串函数的用法_python中字符串内置函数的用法介绍(代码)

    本篇文章给大家带来的内容是关于python中字符串内置函数的用法介绍(代码) ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. capitalize() 首字母大写a='somewor ...

  9. python中print end的用法_python中print用法

    print用法 参考文档: https://blog.csdn.net/sinat_28576553/article/details/81154912 目录 一.print()函数概述 二.变量的输出 ...

最新文章

  1. python显示无效语法怎么处理-Python不支持 i ++ 语法的原因解析
  2. Codeforces Round #408 (Div. 2)
  3. 【渝粤教育】国家开放大学2019年春季 1398分析化学(本) 参考试题
  4. Java、JavaScript、C、C++、PHP、Python都是用来开发什么?赶紧来看看!
  5. cpu线程测试软件,CPU多线程测试:wPrime/国际象棋
  6. .Net控件Telerik全套下载:Telerik Controls 2010 Q2 (附加DLL文件+源码)
  7. python编程是干嘛的-python编程能做什么开发
  8. atitit knowmng知识管理 索引part2
  9. android 模拟器优化,Android模拟器大幅优化 为开发者谋福利
  10. 忘了是出自雪中还是剑来或者就是癞蛤蟆?反正应该是烽火大太监的句子吧。还掺杂了许多别家的,记不清谁写的了,或许有西藏的佛陀
  11. 用迅雷下载百度网盘的文件
  12. 班级学生德育量化管理系统_德育积分学分考核系统_学生操行日常行为规范考核系统
  13. poker游戏编码规则
  14. 数据仓库构建方法论(六):数据建模方法论
  15. 微信公众号 修改 应用签名 不生效
  16. 面试官让你说说你的缺点,你该怎么回答
  17. 系统分析师资料_自学该如何备战系统分析师考试?
  18. Latex 一半黑一半白的圆圈
  19. 一文掌握SPFA算法
  20. 图像融合之泊松编辑(Poisson Editing)(1):简略语言概述算法

热门文章

  1. Drools规则属性,高级语法
  2. iOS开发-写给初学者:OC面向对象的三大特征
  3. 精彩!对外经济贸易大学信息学院人工智能+交叉学科建设研讨会成功举办!
  4. 一个星期快速自学java编程高级语言干货笔记 -实用类
  5. 计算机学院运动会解说词,学院运动会解说词
  6. 织梦CMS v5.7 完美实现导航条下拉二级菜单
  7. order函数的简单使用
  8. 集丰照明|没有副光斑的射灯简直了,小山丘完美
  9. springboot系列(三十一):如何实现excel模板导出成pdf文件?这你得会 | 超级详细,建议收藏
  10. 《ANSYS Workbench有限元分析实例详解(静力学)》——导读