获取创建的对象将被赋予的属性名称

发布于 2024-08-27 22:50:21 字数 548 浏览 7 评论 0原文

在我问这个问题之前,请注意:我想要这个用于调试目的。我知道这将是一些糟糕的黑魔法,但我想在调试期间使用它,这样我就可以更轻松地识别我的对象。

是这样的。我有一些来自类 A 的对象,它创建了一些 B 实例作为属性:

class A(object):
    def __init__(self)
        self.vanilla_b = B()
        self.chocolate_b = B()

class B(object):
    def __init__(self):
        # ...

我想要的是在 B.__init__ 中,它将计算输出 "vanilla_b" 或给定的任何属性名称,然后将其作为 .name 属性添加到该特定的 B 中。

然后在调试时,当我看到一些 B 对象漂浮在周围时,我可以知道它是哪一个。

有什么办法可以做到这一点吗?

Before I ask this, do note: I want this for debugging purposes. I know that this is going to be some bad black magic, but I want to use it just during debugging so I could identify my objects more easily.

It's like this. I have some object from class A that creates a few B instances as attributes:

class A(object):
    def __init__(self)
        self.vanilla_b = B()
        self.chocolate_b = B()

class B(object):
    def __init__(self):
        # ...

What I want is that in B.__init__, it will figure out the "vanilla_b" or whatever attribute name it was given, and then put that as the .name attribute to this specific B.

Then in debugging when I see some B object floating around, I could know which one it is.

Is there any way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

初吻给了烟 2024-09-03 22:50:21

您可以使用 sys._getframe 来获取 B() 被调用,然后您可以使用 inspect.getsourcelines 获取实际的代码行。从那里你可以解析代码行以获取 B() 被分配的内容:

import sys
import inspect

class A(object):
    def __init__(self):
        self.vanilla_b = B()
        self.chocolate_b = B()

class B(object):
    def __init__(self):
        line_num = sys._getframe().f_back.f_lineno
        lines = inspect.getsourcelines( sys.modules[__name__] )[0]
        line = lines[line_num - 1]
        attr = line.split("=")[0].split(".")[1].strip()
        print "B() is being assigned to", attr

A()

如果你将上面的代码放入 python 脚本中并运行它,那么它将打印

B() is being assigned to vanilla_b
B() is being assigned to chocolate_b

但是,这个在 Python 命令提示符下不起作用,因为 __main__ 是内置模块,因此检查模块无法检索其源代码行。因此,您可能希望将其包装在 try/catch 块或其他内容中,以防万一您的代码被任何内置模块调用。

根据记录,这可能是一个坏主意,但是您说您知道这不是一个好的做法,并且您这样做只是为了调试,所以希望您能够明智地使用这种技巧。

You can use sys._getframe to get the line number where B() is called, then you can use inspect.getsourcelines to get the actual line of code. From there you can parse the line of code to get the thing to which B() is being assigned:

import sys
import inspect

class A(object):
    def __init__(self):
        self.vanilla_b = B()
        self.chocolate_b = B()

class B(object):
    def __init__(self):
        line_num = sys._getframe().f_back.f_lineno
        lines = inspect.getsourcelines( sys.modules[__name__] )[0]
        line = lines[line_num - 1]
        attr = line.split("=")[0].split(".")[1].strip()
        print "B() is being assigned to", attr

A()

If you put the above code into a python script and run it, then it will print

B() is being assigned to vanilla_b
B() is being assigned to chocolate_b

However, this won't work at the Python command prompt, since __main__ is a builtin module, and thus the inspect module can't retrieve its source lines. So you might want to wrap this in a try/catch block or something just in case your code ever gets called from any builtin module.

For the record, this is probably a bad idea, but you say that you're aware that it's not good practice and you're only doing it for debugging, so hopefully you'll be able to use this kind of trickery wisely.

眼眸里的快感 2024-09-03 22:50:21

这可能不是您正在寻找的答案,但也许您可以这样做:

class A(object):
    def __init__(self):
        attrs = ('vanilla_b', 'chocolate_b')

        for attr in attrs:
            instance = B()
            setattr(self, attr, instance)
            instance.name = attr

尝试将该行为包装到某个超类中,您可能会很高兴。

This is probably not the answer you are looking for but perhaps you could do something along this:

class A(object):
    def __init__(self):
        attrs = ('vanilla_b', 'chocolate_b')

        for attr in attrs:
            instance = B()
            setattr(self, attr, instance)
            instance.name = attr

Try wrapping that behavior to some superclass and you might be good to go.

独守阴晴ぅ圆缺 2024-09-03 22:50:21

如果您可以控制代码,那么最好简单地执行此操作,然后依赖一些黑魔法,例如,否则

class A(object):
    def __init__(self)
        self.vanilla_b = B(name="vanilla_b")
        self.chocolate_b = B(name="chocolate_b")

您可以使用检查模块来遍历上一帧中的局部变量和自身并执行一些巫术。

If you have control over code then it is better to do it simply then rely on some black magic e.g. do

class A(object):
    def __init__(self)
        self.vanilla_b = B(name="vanilla_b")
        self.chocolate_b = B(name="chocolate_b")

otherwise you can use inspect module to go thru locals and self in prev frame and do some vodoo.

淡淡離愁欲言轉身 2024-09-03 22:50:21

不是很神奇,但是:

class A(object):
    def __init__(self)
        self.vanilla_b = B(self)
        self.chocolate_b = B(self)

和:

class B(object):
    def __init__(self, a):
        for i in dir(a):
            if getattr(a, i) == self:
                pass # store it somewhere now

编辑:抱歉,这行不通。 B.init 在 A 中的引用设置之前执行。

Not very magical, but:

class A(object):
    def __init__(self)
        self.vanilla_b = B(self)
        self.chocolate_b = B(self)

and:

class B(object):
    def __init__(self, a):
        for i in dir(a):
            if getattr(a, i) == self:
                pass # store it somewhere now

EDIT: Sorry, this won't work. B.init is executed before references in A are set.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文