我想:
检查字符串是否包含对象属性
如果是,则访问属性
所以对于类对象

class Person(object):
    name = ""
    age = 0
    major = ""

    def __init__(self, name="", surname="", father="", age =0):
        self.name = name
        self.surname = surname
        self.father = father
        self.age = age
        self.identity = name +" "+ surname
    def __str__(self):
        return self.identity

    __repr__ = __str__

和对象
person = Person("Earl", "Martin", "Jason", 40)

我想要字符串“名字是什么”
返回person.name
(我已经知道字符串是关于哪个对象的)
最基本的解决方案是对每个存在的属性执行case,但是实际的代码有很多,我确信我不需要手动地将它们写出来,我只是刚刚开始编程,所以我不确定为此使用什么语法
感谢任何帮助

最佳答案

正如其他人所指出的,getattr通常是有用的。
hasattr的效用较小;在内部,它基本上是getattr/try块中的一个except AttributeError:调用(如果AttributeError发生,则返回False,没有异常意味着True),因此,如果您考虑如下代码:

if hasattr(myobj, attrname):
    attr = getattr(myobj, attrname)
    ...

只需使用:
try:
    attr = getattr(myobj, attrname)
except AttributeError:
    pass
else:
    ...

为了避免LEGB查找、函数调用和属性查找的数量加倍。
或者,对于重复拉取命名属性,operator.attrgetter基本上允许您制作一个优化版本的getattr,该版本预先将属性名称绑定到查找(使其非常适合与mapfilter函数一起使用,因为它使它们比等价的listcomps/genexpr更有效)。
除此之外,取决于你的目标是什么,the dir和(由于类that use __slots__ to define a known set of variables to reduce memory usage and prevent auto-vivification的问题,vars function可能更不可靠)。
例如,在从字符串中提取与单词对应的任何属性的示例中,可以使用vars()/dir()对合法属性名进行批量标识,并根据顺序、唯一性等的重要性选择filterset操作(或混合操作):
from future_builtins import filter  # Only on Py2, not Py3
import operator
import re

def query_obj(obj, querystr):
    # Extract list of legal attribute names from string
    words = re.findall(r'\w+', querystr)

    # Reduce to names present on object's __dict__; no need to construct temporaries
    attrnames = filter(vars(obj).__contains__, words)
    # Alternate if __slots__ might be an issue (temp list & frozenset):
    attrnames = filter(frozenset(dir(obj)).__contains__, words)
    # Or combine the two to be sure (on Py3, use .keys() instead of .viewkeys())
    # (temp list and set):
    attrnames = filter((vars(obj).viewkeys() | dir(obj)).__contains__, words)

    # Convenient way to get all names discovered at once; returns single object
    # for single attr, tuple of objects for multiple attrs:
    return operator.attrgetter(*attrnames)(obj)

    # If you want a tuple unconditionally, use this instead:
    return tuple(getattr(obj, name) for name in attrnames)

    # Or to only return the first attribute encountered, raising StopIteration
    # if no attributes are found:
    return next(getattr(obj, name) for name in attrnames)

那么用法是:
>>> person = Person("Earl", "Martin", "Jason", 40)
>>> query_obj(person, "What is the name?")
'Earl'  # Would be ('Earl',) in unconditional tuple case
>>> query_obj(person, "What is the name and surname?")
('Earl', 'Martin')  # Would be 'Earl' in single return case

09-10 00:39
查看更多