python - Python 中 hasattr 的逆运算

标签 python

hasattr(obj, attribute) 用于检查一个对象是否具有指定的属性,但是给定一个属性是否有办法知道它在哪里(全部)定义?

假设我的代码获取属性(或类方法)的名称作为字符串,我想调用 classname.attribute 但我没有类名。

我想到的一个解决方案是这个

def finder(attr):
    for obj in globals():
        try:
            if globals()[obj].__dict__[attr]:
                return(globals()[obj])
        except:
            ...

用法:

class Lime(object):
    @classmethod
    def lfunc(self):
        print('Classic')

getattr(finder('lfunc'),'lfunc')() #Runs lfunc method of Lime class

我很确定这不是最好的(甚至是正确的方法)。有人可以提供更好的方法吗。

最佳答案

总是“可能的”。是否可取是另一段历史。

一种快速而肮脏的方法是线性迭代所有类并检查是否有任何定义您拥有的属性。当然,这是有冲突的,它会产生第一个具有这样一个命名属性的类。如果它存在于不止一个中,则由您决定您想要哪个:

def finder(attr):
    for cls in object.__subclasses__(): 
         if hasattr(cls, attr):
              return cls
    raise ValueError

它不是在“globals”中搜索,而是搜索“object”的所有子类 - 因此要查找的类不需要位于 finder 函数所在模块的命名空间中。

但是,如果您的方法在您正在搜索的一组类中是唯一的,也许您可​​以组装所有方法的映射并使用它来调用它们。

让我们假设您所有的类都来自名为“Base”的类:

mapper = {attr_name:getattr(cls, attr_name)  for cls in base.__subclasses__() for attr_name, obj in cls.__dict__.items()
             if isinstance(obj, classmethod) }

然后你用mapper['attrname']()调用它们

这避免了在每个方法调用时进行线性搜索,因此会好得多。

- 编辑 -

__subclassess__ 只是找到一个类的直接子类,而不是继承树——所以它在“现实生活”中没有用处——也许是在 OP 的特定情况下手。
如果需要在继承树中查找内容,则还需要对每个子类进行递归。

至于旧式类:这当然行不通——这是在新代码中默认破坏它们的动机之一。

至于非类属性:无论如何只能在检查实例时找到它们 - 所以必须考虑另一种方法 - 似乎不是 O.P. 关心的问题。

关于python - Python 中 hasattr 的逆运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16042880/

相关文章:

python - 列表理解示例

python - 使用列表中的值过滤字典中的键、值

python - 从其他数据框中选择具有特定条件的行

Python 变量和函数注释引发 AttributeError

Python gi.repository Gst.ElementFactory.make 返回 None?

python - 以编程方式调用 VS 开发人员命令提示符中的命令

python - wave.Error : unknown format: 3 arises when trying to convert a wav file into text in Python

python - pandas groupby 可以聚合成一个列表,而不是 sum、mean 等吗?

python - 如何在 Flask + gunicorn 应用程序中查看异常?

python - R 作为通用编程语言