我感觉我在Python中遇到了一种相当奇怪的行为.自己try 一下:

import inspect

class SomeClass:
    def __init__(self):
        inspect.getmembers(self, predicate=inspect.ismethod)

    def this_is_okay(self):
        raise Exception('an error that may be thrown')

    @property
    def this_is_not_okay(self):
        raise Exception('an error that may be thrown')

    @property
    def but_this_is_okay(self):
        if True:
            raise Exception('an error that may be thrown')

如果存在用@property装饰的方法,判断类的方法将导致错误,但前提是它在第一个缩入级别引发错误.

怎么可能?我该如何解决这个问题?

P.S.我这样判断的原因是我试图按照类方法(实际的可调用对象)在类中定义的顺序获取类方法的array.

推荐答案

但您实际上并没有在类上调用inspect.getmembers,因为self指的是类的实例. 当它试图使用getattr getter(您可以从Traceback中推断出来)时,就会发生错误,并且鉴于SomeClass().this_is_not_okay将有效地引发异常,这将打破inspect.getmembers. 这实际上是a known issue个,自2018年以来一直开放. 此外,您关于"但只有当它在第一个缩入级别引发错误时"的断言是不正确的,因为inspect.getmembersthis_is_not_okay处简单地终止,并出现异常(尽管将条件更改为if False将使其工作,因为它将停止执行raise声明).

现在,您描述了您既定的目标是获得课程中定义事物的顺序,好吧,您必须通过课程. 示例:

import inspect

class SomeClass:
    def this_is_okay(self):
        raise Exception('an error that may be thrown')

    @property
    def this_is_not_okay(self):
        raise Exception('an error that may be thrown')

    @property
    def but_this_is_okay(self):
        if False:
            raise Exception('an error that may be thrown')

some_ins = SomeClass()
print(inspect.getmembers(type(some_ins), predicate=inspect.isfunction))

上面应该产生类似的内容:

[('this_is_okay', <function SomeClass.this_is_okay at 0x7f166ae1a980>)]

如果使用Python 3.11或更高版本,则可以使用inspect.getmembers_static:

print(inspect.getmembers_static(some_ins, predicate=inspect.isfunction))

这实际上起到了同样的作用.

请注意,我将断言更改为inspect.isfunction,因为类定义一般没有方法,但这些函数通常会成为类实例中的函数,因此区别应该是最小的.

如果您必须使用inspect.ismethod断言,则可能必须获取类实例的每个成员,然后应用您想要的过滤.

Python相关问答推荐

PyQt5如何将pyuic 5生成的Python类添加到QStackedWidget中?

Python:记录而不是在文件中写入询问在多文件项目中记录的最佳实践

使用matplotlib pcolormesh,如何停止从一行绘制的磁贴连接到上下行?

Pandas 除以一列中出现的每个值

可变参数数量的重载类型(args或kwargs)

将输入管道传输到正在运行的Python脚本中

根据二元组列表在pandas中创建新列

Python键入协议默认值

在vscode上使用Python虚拟环境时((env))

给定高度约束的旋转角解析求解

如何更新pandas DataFrame上列标题的de值?

网格基于1.Y轴与2.x轴显示在matplotlib中

用SymPy在Python中求解指数函数

如何在Great Table中处理inf和nans

如何在Python 3.9.6和MacOS Sonoma 14.3.1下安装Pyregion

根据Pandas中带条件的两个列的值创建新列

在极点中读取、扫描和接收有什么不同?

Python将一个列值分割成多个列,并保持其余列相同

如何在Gekko中处理跨矢量优化

python3中np. divide(x,y)和x/y有什么区别?'