为了账号安全,请及时绑定邮箱和手机立即绑定

如何发现类重新定义?

如何发现类重新定义?

斯蒂芬大帝 2021-06-29 09:00:27
这是一个非常简单的设置:class A(object):    x = 1class B(object):    x = 2class C(object):    x = 3class B(B):    x = 4class C(object):    x = 5print A.x, B.x, C.x输出预期:1, 4, 5是否有可能检测到 B 已被“重新定义”但 C 已被“替换”?是在创建阶段还是随后通过检查对象?这些类被用作配置对象,上面有一个加载器类,它导入模块,然后自省以找到类及其属性,然后应用程序将它们用于实例命名参数。例如class tcp_port(number):    minimum = 1024    maximum = 2048实际上,python 只是用作一种方便的脚本语言来定义主应用程序中的参数。这些文件可供最危险的人编辑: 客户 因此,要求能够在运行时检测类是否(意外地)重用了已定义的名称,但要安全地通过偶尔的情况其中一个类被重新定义,然后调整或添加一些属性:class tcp_port(tcp_port):    maximum = 4096所以......我希望有一些运行时健全性检查程序,而不是类似 lint 的解决方案。此外,这需要在定义类而不是实例化时发生。...是否有全局函数被调用来创建一个类(或任何其他对象)?有点像有__new__但在全球范围内?
查看完整描述

2 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

如果该类是就地重新定义的,它将在 MRO 中保留其自身的旧版本:


>>> [x for x in A.mro() if x.__name__ == A.__name__]

[__main__.A]

>>> [x for x in B.mro() if x.__name__ == B.__name__]

[__main__.B, __main__.B]

>>> [x for x in C.mro() if x.__name__ == C.__name__]

[__main__.C]

所以你可以检测到这种情况:


def has_redefinition_inplace(classobj):

    types = [x for x in classobj.mro() if x.__name__ == classobj.__name__]

    return len(types) > 1

这不会是 100% 可靠的,因为可能存在从不同模块进入 MRO 的合法冲突类名称。


查看完整回答
反对 回复 2021-07-06
?
大话西游666

TA贡献1817条经验 获得超14个赞

一个好的 linter 会警告没有使用的重新声明。一个好的 IDE 会直接在编辑器中 lint。

例如,PyCharm 将使用警告颜色突出显示这些类名:

//img1.sycdn.imooc.com//60e3c89c0001ba6605140359.jpg

发现这些问题的另一个好方法是在您的测试套件中使用覆盖率。名称被覆盖的函数(常见的复制粘贴错误)在函数体中不能有测试覆盖。


查看完整回答
反对 回复 2021-07-06
  • 2 回答
  • 0 关注
  • 206 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号