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

在Python中构build一个新的类对象时,我希望能够根据类的实例名称创build一个默认值,而不用传入额外的参数。 我怎样才能做到这一点? 这是我想要的基本伪代码:

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" 

实例没有名字。 当全局名称ThisObject绑定到通过评估SomeObject构造函数创build的实例时,构造函数已经完成运行。

如果你想要一个对象有一个名字,只需要在构造函数中传入一个名字。

 def __init__(self, name): self.name = name 

那么,几乎有办法做到这一点:

 #!/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 

回溯模块允许您查看用于调用SomeObject()的代码。 用一个小小的string来说明, text[:text.find('=')].strip()你可以猜到def_name是什么。

但是,这个破解是脆弱的。 例如,这不太好:

 ThisObject,ThatObject = SomeObject(),SomeObject() print ThisObject.defined_name # ThisObject,ThatObject print ThatObject.defined_name # ThisObject,ThatObject 

所以,如果你使用这个黑客,你必须记住,你必须使用简单的python语句调用SomeObject():

 ThisObject = SomeObject() 

顺便说一句,作为使用追溯的进一步例子,如果你定义

 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)) 

那么你可以打电话

 x=3.14 pv(x) # x: 3.14 

打印variables名称及其值。

你可以在你的类中创build一个方法来检查当前帧中的所有variables,并使用hash()来查找selfvariables。

这里提出的解决scheme将返回所有指向实例对象的variables。

在下面的类中,使用isinstance()来避免应用hash()时的问题,因为像numpy.arraylist这样的对象是不可更改的。

 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 

以下testing已经完成:

 def test(): a = A() b = a c = b print c.get_my_name() 

结果是:

 test() #['a', 'c', 'b'] 

这是行不通的,试想一下: a = b = TheMagicObjet() 。 名称对价值没有影响,他们只是指向它们。

一个可怕的,可怕的方式来完成这个是扭转责任:

 class SomeObject(): def __init__(self, def_name): self.defined_name = def_name globals()[def_name] = self SomeObject("ThisObject") print ThisObject.defined_name 

如果你想支持全球范围以外的东西,那么你就得做更糟糕的事情。

在Python中,所有数据都存储在对象中。 另外,一个名字可以绑定一个对象,之后可以用这个名字查找这个对象。

这个对象的名字,如果有的话,它可能会被绑定。 它可能会被绑定到几十个不同的名字,或者没有。 而且,Python没有任何指向对象名称的“反向链接”。

考虑这个例子:

 foo = 1 bar = foo baz = foo 

现在,假设你有一个值为1的整数对象,并且你想向后工作并find它的名字。 你打印什么? 三个不同的名字有这个对象绑定到他们,都是同样有效的。

 print(bar is foo) # prints True print(baz is foo) # prints True 

在Python中,名称是访问对象的一种方式,因此无法直接使用名称。 您可以search各种名称空间,直到find与感兴趣对象绑定的名称,但我不build议这样做。

如何获得python中的variables的string表示forms?

有一个名为“像Pythonista一样的代码”的着名演示文稿,将这种情况总结为“其他语言具有variables”,“Python具有名称”

http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables

我认为,如果名称是任何对象的指针,名称就很重要。如果没有问题:

 foo = 1 bar = foo 

我知道foo指向1,并且bar指向相同的内存空间中相同的值1。 但是我想创build一个带有添加对象的函数的类。

 Class Bag(object): def __init__(self): some code here... def addItem(self,item): self.__dict__[somewaytogetItemName] = item 

所以,当我像下面那样实例化类包时:

 newObj1 = Bag() newObj2 = Bag() newObj1.addItem(newObj2)I can do this to get an attribute of newObj1: newObj1.newObj2 

最好的方法是将名称传递给构造函数,就像在select的答案中一样。 但是,如果您真的想避免要求用户将名称传递给构造函数,则可以执行以下hack操作

如果从命令行使用“ThisObject = SomeObject()”创build实例,则可以从命令历史logging中的命令string获取对象名称:

 import readline import re class SomeObject(): def __init__(self): cmd = readline.get_history_item(readline.get_current_history_length()) self.name = re.split('=| ',cmd)[0] 

如果您使用'exec'命令创build实例,则可以通过以下方式处理:

 if cmd[0:4] == 'exec': self.name = re.split('\'|=| ',cmd)[1] # if command performed using 'exec' else: self.name = re.split('=| ',cmd)[0]