no se puede hacer de ordinario, aunque esto se puede lograr mediante el uso de la introspección e instalaciones destinado a la depuración de un programa. Sin embargo, el código debe ejecutarse desde un archivo ".py", y no solo desde un código byte compilado, o dentro de un módulo comprimido, ya que depende de la lectura del código fuente del archivo, desde el método que debe encontrar sobre "dónde está". corriendo".
El truco es acceder al marco de ejecución donde se inicializó el objeto - con inspect.currentframe - el objeto frame tiene un valor "f_lineno" que indica el número de línea donde se llama al método del objeto (en este caso, __init__
) ha sido llamado. La función inspeccionar.nombre de archivo permite recuperar el código fuente del archivo y buscar el número de línea apropiado.
Un análisis ingenuo luego mira la parte anterior a un signo "=", y asume que es la variable que contendrá el objeto.
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()
que no funciona para múltiples assignents, expresiones que componen el objeto antes de la assignemtn se hace, los objetos que se agregan a las listas o añadirse a los diccionarios o en grupos, instancias de objetos de inicialización de for
bucles, y Dios sabe qué más situaciones - Y tenga en cuenta que después de la primera atribución, el objeto también podría ser referenciado por cualquier otra variable.
línea de Botton: que es posible, sino como un juguete - que no puede ser utilizado i código de producción - sólo tiene el nombre varibal ser pasado como una cadena durante la inicialización del objeto, al igual que uno tiene que hacer al crear un
la "forma correcta" collections.namedtuple
a hacerlo, si usted está necesitando el nombre, es pasar de forma explícita el nombre a la inicialización de objetos, como un parámetro de cadena, como en:
class A(object):
def __init__(self, name):
self.name = name
x = A("x")
Y aún así, si es absolutamente necesario escribir el nombre de los objetos solo una vez, allí es otra forma - sigue leyendo. Debido a la sintaxis de Python, algunas asignaciones especiales, que no utilizan el operador "=", permiten que un objeto sepa que tiene asignado un nombre. Por lo tanto, otros términos de estado que realizan asignadores en Python son las palabras clave para, con, definición y clase. Es posible abusar de esto, ya que una creación de clase y una definición de función son declaraciones de asignación que crean objetos que "conocen" sus nombres.
Centrémonos en la declaración def
. Por lo general, crea una función. Pero el uso de un decorador puede utilizar "def" para crear cualquier tipo de objeto - y tienen el nombre que se utiliza para la función a disposición del constructor:
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
(Esta última forma de hacerlo podría ser utilizado en código de producción, a diferencia del que recurre a leer el archivo fuente)
No es posible - aunque recientemente (hace 3-4 meses) en las ideas de la lista de Python ha habido alguna discusión sobre agregar una capacidad a algo como esto. – jsbueno
La respuesta corta es: no, no intentes ...y la verdadera respuesta es sí, pero no intentes ... :) – wim