在Python中访问实例名称以进行打印

2024-05-13 04:18:21 发布

您现在位置:Python中文网/ 问答频道 /正文

作为“像计算机科学家一样思考”中问题17.6的一部分,我写了一个名为“袋鼠:

class Kangaroo(object):

    def __init__(self, pouch_contents = []):
        self.pouch_contents = pouch_contents

    def __str__(self):
        '''
        >>> kanga = Kangaroo()
        >>> kanga.put_in_pouch('olfactory')
        >>> kanga.put_in_pouch(7)
        >>> kanga.put_in_pouch(8)
        >>> kanga.put_in_pouch(9)
        >>> print kanga
        "In kanga's pouch there is: ['olfactory', 7, 8, 9]"
        '''

        return "In %s's pouch there is: %s" % (object.__str__(self), self.pouch_contents)

    def put_in_pouch(self, other):
        '''
        >>> kanga = Kangaroo()
        >>> kanga.put_in_pouch('olfactory')
        >>> kanga.put_in_pouch(7)
        >>> kanga.put_in_pouch(8)
        >>> kanga.put_in_pouch(9)
        >>> kanga.pouch_contents
        ['olfactory', 7, 8, 9]
        '''

        self.pouch_contents.append(other)

让我发疯的是,我希望能够编写一个字符串方法,该方法可以通过所写的__str__下面的单元测试。我现在得到的是:

^{pr2}$

基本上,我想知道是否有一些函数可以在kanga=Kangaroo上执行,这样函数的输出就是这5个字符,即function(kanga)—>;“kanga”。在

有什么想法吗?在

编辑: 阅读第一个答案让我意识到有一种更简洁的方式来问我最初的问题。有没有办法重写__init__以使下面的代码在编写时是有效的?在

>>> somename = Kangaroo()
>>> somename.name
'somename'

Tags: inselfobjectputinitdefcontentskangaroo
3条回答

请您解释一下您所创建的透视图的名称:

marsupials = []
marsupials.append(Kangaroo()) 

This classic essay by the effbot给出了很好的解释。在

回答编辑中修改过的问题:不

既然您在一篇评论中说得很清楚,并且说这个命名练习的全部目的是区分与可变默认参数相关联的调试目的的对象:

至少在Python的CPython实现中,在任何给定的时间,所有现有对象都有一个惟一的ID,这个ID可以通过id(obj)获得。这对于调试来说已经足够了。注意,如果一个对象被删除,这个ID(内存地址)可以被随后创建的对象重用。在

我不打算把这个贴出来,但如果你只想把它用于调试,那么你可以:

import sys

class Kangaroo(object):
    def __str__(self):
        flocals = sys._getframe(1).f_locals
        for ident in flocals:
            if flocals[ident] is self:
                name = ident
                break
        else:   
            name = 'roo'
        return "in {0}'s pouch, there is {1}".format(name, self.pouch_contents)

kang = Kangaroo()
print kang

这依赖于CPython(AFAIK),不适用于生产代码。如果实例位于任何类型的容器中,它将不起作用,并且随时可能因任何原因而失败。不过,它应该对你有好处。在

它的工作原理是从堆栈框架中获取f_locals字典,该框架表示调用print kang的命名空间。f_locals的键是帧中变量的名称,因此我们只需循环遍历它并测试每个条目是否为self。如果是这样,我们break。如果break没有执行,那么我们找不到条目,循环else子句按请求分配值'roo'。在

如果您想从某种容器中取出它,您需要扩展它来查看f_locals中的任何容器。如果键是dictlike容器,则可以返回键;如果键是tuple或list,则返回索引。在

class Kangaroo(object):

    def __init__(self, pouch_contents=None, name='roo'):
        if pouch_contents is None:
            self.pouch_contents = []  # this isn't shared with all other instances
        else:
            self.pouch_contents = pouch_contents
        self.name = name
    ...

kanga = Kangaroo(name='kanga')

注意,而不是在参数中的=周围加空格是一种好的方式

相关问题 更多 >