在类__init __()中获取实例名称

Ako*_*exx 18 python variables class object instance

在python中构建一个新的类对象时,我希望能够根据类的实例名创建一个默认值,而不需要传递额外的参数.我怎么能做到这一点?这是我正在尝试的基本伪代码:

class SomeObject():
    defined_name = u""

    def __init__(self, def_name=None):
        if def_name == None:
            def_name = u"%s" % (<INSTANCE NAME>)
        self.defined_name = def_name

ThisObject = SomeObject()
print ThisObject.defined_name   # Should print "ThisObject"
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 22

好吧,几乎有办法做到这一点:

#!/usr/bin/env python
import traceback
class SomeObject():
    def __init__(self, def_name=None):
        if def_name == None:
            (filename,line_number,function_name,text)=traceback.extract_stack()[-2]
            def_name = text[:text.find('=')].strip()
        self.defined_name = def_name

ThisObject = SomeObject()
print ThisObject.defined_name 
# ThisObject
Run Code Online (Sandbox Code Playgroud)

回溯模块允许您查看用于调用SomeObject()的代码.通过一些字符串争论,text[:text.find('=')].strip()你可以猜出def_name应该是什么.

但是,这种黑客很脆弱.例如,这不能很好地工作:

ThisObject,ThatObject = SomeObject(),SomeObject()
print ThisObject.defined_name
# ThisObject,ThatObject
print ThatObject.defined_name 
# ThisObject,ThatObject
Run Code Online (Sandbox Code Playgroud)

因此,如果你要使用这个hack,你必须记住你必须使用简单的python语句调用SomeObject():

ThisObject = SomeObject()
Run Code Online (Sandbox Code Playgroud)

顺便说一句,作为使用回溯的另一个例子,如果你定义

def pv(var):
    # stack is a list of 4-tuples: (filename, line number, function name, text)
    # see http://docs.python.org/library/traceback.html#module-traceback
    #
    (filename,line_number,function_name,text)=traceback.extract_stack()[-2]
    # ('x_traceback.py', 18, 'f', 'print_var(y)')
    print('%s: %s'%(text[text.find('(')+1:-1],var))
Run Code Online (Sandbox Code Playgroud)

然后你可以打电话

x=3.14
pv(x)
# x: 3.14
Run Code Online (Sandbox Code Playgroud)

打印变量名称及其值.

  • 首先它被称为黑客,然后是回旋,...很快它将被称为成语:) (11认同)
  • 哇,这是如此迂回,它几乎喊出"你不应该这样做!" :) (4认同)

Jon*_*erg 19

实例没有名称.由当时的全局名称ThisObject绑定到通过评估创建的实例SomeObject构造函数,构造函数运行完毕.

如果希望对象具有名称,只需在构造函数中传递名称即可.

def __init__(self, name):
    self.name = name
Run Code Online (Sandbox Code Playgroud)

  • 根据你的定义,没有"变量"这样的东西.在某种语言中,某个对象只能绑定一个名称? (4认同)

Sau*_*tro 6

您可以在类中创建一个方法,检查当前帧中的所有变量并用于hash()查找self变量.

这里提出的解决方案将返回指向实例对象的所有变量.

在下面的类中,isinstance()用于避免应用时出现问题hash(),因为某些对象(例如a numpy.array或a)list是不可删除的.

import inspect
class A(object):
    def get_my_name(self):
        ans = []
        frame = inspect.currentframe().f_back
        tmp = dict(frame.f_globals.items() + frame.f_locals.items())
        for k, var in tmp.items():
            if isinstance(var, self.__class__):
                if hash(self) == hash(var):
                    ans.append(k)
        return ans
Run Code Online (Sandbox Code Playgroud)

已完成以下测试:

def test():
    a = A()
    b = a
    c = b
    print c.get_my_name()
Run Code Online (Sandbox Code Playgroud)

结果是:

test()
#['a', 'c', 'b']
Run Code Online (Sandbox Code Playgroud)