You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用getattr调用方法时Case1返回None的原因及类Case1写法实现

原因说明

getattr是Python内置的属性查找函数,它的第二个参数仅接受纯属性名字符串,不会自动解析字符串中包含的括号、传参等调用语法,只会把传入的整个字符串做完全匹配,查找对象上的同名属性。

你写的Case1中传入的属性名是"find('span',{'class':'txt'})",代码会直接在i[0]对象上查找名字完全等于这个长字符串的属性,根本不会触发find方法的调用逻辑。而BeautifulSoup的标签对象重写了属性查找规则,访问不存在的普通属性时不会抛出AttributeError,而是默认返回None,这就是你拿到None返回值的根本原因。

Case2能正常运行,是因为传给getattr的第二个参数是纯属性名'find',正确拿到了对象绑定的find方法对象,之后再手动传入参数执行调用,所以能得到预期的标签结果。

类Case1形式的实现方案

如果要实现「动态指定方法+参数完成调用」的效果,可以选择以下几种可行方案:

  • 标准getattr写法(最推荐,可读性、安全性最好)
    拆分属性获取和调用两个步骤,是getattr的标准使用方式:
    # 先获取绑定的方法对象
    find_func = getattr(i[0], "find")
    # 再传入参数执行调用
    test = find_func('span', {'class': 'txt'})
    
  • methodcaller封装写法
    借助标准库operator的methodcaller,可以提前把方法名、固定参数封装成可调用对象,需要执行时直接传入目标实例即可:
    from operator import methodcaller
    # 提前封装方法名和入参
    find_caller = methodcaller("find", 'span', {'class': 'txt'})
    # 传入实例直接拿到调用结果
    test = find_caller(i[0])
    
  • eval动态执行写法(不推荐,存在安全风险)
    如果一定要把完整调用逻辑写在单个字符串里,可以用eval执行拼接好的表达式,但绝对不能在处理用户可控输入的场景使用,会存在严重的代码注入漏洞:
    # 构造完整的执行表达式
    expr = """i[0].find('span', {'class': 'txt'})"""
    test = eval(expr)
    

注意:生产环境优先选择前两种方案,非必要不要使用eval。

内容的提问来源于stack exchange,提问作者KimGyeongMin-KR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 05:00:57