Разработка таблицы HBase для отслеживания состояния сложного объекта

Это невозможно сделать обычно, хотя это может быть достигнуто с помощью интроспекции и средств, предназначенных для отладки программы. Код должен выполняться из файла «.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

(Последний способ сделать это можно использовать в производственном коде, в отличие от того, который прибегает к чтению исходного файла)

0
задан mcjkwlczk 17 January 2019 в 17:48
поделиться