是否有可能确定我们是否处于循环的中间?

Is it possible to identify if we are in the middle of a loop?

是否可以识别我们是否处于循环的中间?

我想让 class 自动识别变量是否来自迭代器。

我检查了检查模块但没有成功。也许有一些范围标识符或一些出色的魔术方法操作可以在代码在循环内运行时进行标记。

这里举个例子让我明白。如何设置inside_loop学生属性?

class Student:
    def __init__(self, id):
        self.id = id
        self.inside_loop = ???
    def print_grade(self):
        if self.inside_loop:
            print("you are inside a loop")
        else:
            print("checking grade...")     

>>> S = Student(1)
>>> S.print_grade()
>>> checking grade...

>>> student_ids = [1, 2, 3]
>>> for student in student_ids:
>>>     S = Student(student) 
>>>     S.print_grade()
>>>       
>>> you are inside a loop
>>> you are inside a loop
>>> you are inside a loop

提前致谢。

这道题我进步了一点。我使用了 python 的 astinspect 标准模块。由于我们有一些令人担忧的评论,如果您指出下面代码中可能存在的错误,我将不胜感激。至此,解决了原来的问题

使用 inspect.currentframe().f_back 我得到了实例化 class 的框架。然后框架用于构建抽象树。对于每个树节点,都设置了父属性。最后,我 select 与原始帧具有相同行号的节点 class 实例化分配并检查此节点父节点是 ast.For, ast.While, 还是 ast.AsyncFor.

它在纯 python shell. 中不起作用,请参阅 get ast from python object in interpreter.

中的讨论
import ast
import inspect

class Student:

    def __init__(self, id):
        self.id = id
        self.previous_frame = inspect.currentframe().f_back
        self.inside_loop = self._set_inside_loop()
    
    def _set_inside_loop(self):
    
        loops = ast.For, ast.While, ast.AsyncFor
        nodes = ast.parse(inspect.getsource(self.previous_frame))
    
        for node in ast.walk(nodes):
            try:
                for child in ast.iter_child_nodes(node):
                    child.parent = node
            
                instantiate_class = node.lineno == self.previous_frame.f_lineno
                loop_parent = isinstance(node.parent, loops)
            
                if instantiate_class & loop_parent:
                    return True
            except Exception:
                continue
        else:
            return False
    
    def print_grade(self):
        if self.inside_loop:
            print("you are inside a loop")
        else:
            print("checking grade...")  

现在我们有:

d = Student(4)
d.print_grade()

>>> checking grade...

students = [1,2,3]
for i in students:
    s = Student(i)
    s.print_grade()

>>> you are inside a loop
>>> you are inside a loop
>>> you are inside a loop

i = 1
while i<4:
    s = Student(i)
    s.print_grade()
    i +=1

>>> you are inside a loop
>>> you are inside a loop
>>> you are inside a loop