在类__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()
来查找self
variables。
这里提出的解决scheme将返回所有指向实例对象的variables。
在下面的类中,使用isinstance()
来避免应用hash()
时的问题,因为像numpy.array
或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
以下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]