Это невозможно сделать обычно, хотя это может быть достигнуто с помощью интроспекции и средств, предназначенных для отладки программы. Код должен выполняться из файла «.py», хотя, а не только скомпилированного байт-кода или внутри заархивированного модуля, поскольку он полагается на чтение исходного кода файла, из метода, который должен найти «где это running ".
Фокус в том, чтобы получить доступ к кадру выполнения, в котором объект был инициализирован, - с помощью inspect.currentframe - объект фрейма имеет значение« f_lineno », в котором указывается номер строки, где вызов объекта метод (в данном случае __init__
). Функция inspect.filename позволяет извлекать исходный код для файла и извлекать соответствующий номер строки.
Наивный анализ затем заглянет в часть, предваряющую знак «=», и предполагает, что это переменная, которая будет содержать объект.
from inspect import currentframe, getfile
class A(object):
def __init__(self):
f = currentframe(1)
filename = getfile(f)
code_line = open(filename).readlines()[f.f_lineno - 1]
assigned_variable = code_line.split("=")[0].strip()
print assigned_variable
my_name = A()
other_name = A()
Это не будет работать для нескольких назначений, выражений, составляющих объект до создания assignemtn, объектов, добавляемых к спискам или добавляемых к словарям или наборам, экземпляра объекта в инциализации петель for
, и Бог знает, что больше ситуаций - и имейте в виду, что после
Botton line: возможно , но как игрушка - он не может быть использован i производственный код - просто нужно, чтобы имя переменной было передано как строка во время инициализации объекта, так же, как это нужно делать при создании collections.namedtuple
. «Правильный путь» для этого, если вам нужно имя , заключается в том, чтобы явно передать имя инициализации объекта в качестве параметра строки, например, в:
class A(object):
def __init__(self, name):
self.name = name
x = A("x")
И все же, если абсолютно необходимо вводить имя объекта только один раз, есть еще один путь - читайте дальше. Из-за синтаксиса Python некоторые специальные назначения, не использующие оператор «=», позволяют объекту знать, что ему присвоено имя. Таким образом, другие statemtns, которые выполняют назначающие функции в Python, являются ключевыми словами for, with, def и class. Возможно, это злоупотребление, так как specfically создание класса и определение функции являются операторами присваивания, которые создают объекты, которые «знают» их имена.
Давайте сосредоточимся на утверждении def
. Он обычно создает функцию. Но с помощью декоратора вы можете использовать «def» для создания любого объекта - и имя, используемое для функции, доступной для конструктора:
class MyObject(object):
def __new__(cls, func):
# Calls the superclass constructor and actually instantiates the object:
self = object.__new__(cls)
#retrieve the function name:
self.name = func.func_name
#returns an instance of this class, instead of a decorated function:
return self
def __init__(self, func):
print "My name is ", self.name
#and the catch is that you can't use "=" to create this object, you have to do:
@MyObject
def my_name(): pass
(Последний способ сделать это можно использовать в производственном коде, в отличие от того, который прибегает к чтению исходного файла)