Строка, которая инициализируется лениво в Python - PullRequest
2 голосов
/ 02 апреля 2012

Я понял, что при выводе из str и перезаписи __new__ вы можете перезаписывать строки.Вы знаете какую-нибудь магию, которая создала бы лениво инициализированную строку?Поэтому

def f(a, b):
    print("f called")
    return a+b

s=f("a", "b")
print("Starting")
print(s)

как я могу добавить декоратор к функции f, чтобы эта функция выполнялась только после того, как"Запуск" (в основном при первом доступе)?Кажется хитрым ...:)

Я могу сделать это, когда объекты возвращаются, потому что там я перехватываю доступ к атрибутам.Тем не менее, строка не использует доступ к атрибутам?

Ответы [ 3 ]

3 голосов
/ 02 апреля 2012

Там могут быть более простые способы делать то, что вы хотите - Тем не менее, я однажды написал универсальный «ленивый декоратор» для универсальных функций, который делает именно то, что вы просите - воспринимать это сложнее именно потому, что он будет работать практически для любого типа объектов, возвращаемых функциями.

Основная идея такова: для данного существующего объекта Python фактически не «использует» его значение, но для вызова одного из методов «dunder» (magic double «__») в классе объекта - будь то для его представления (вызывает либо __repr__ __str__ __unicode__), получения из него атрибутов, совершения вызовов, использования его в качестве оператора в арифметической операции и так далее.

Итак, этот декоратор, когда вызывается функция, в основном сохраняет параметры и ожидает вызова любого из этих магических методов, после чего он выполняет вызов originall и кэширует возвращаемое значение -

Код соруса здесь:

https://bitbucket.org/jsbueno/metapython/src/f48d6bd388fd/lazy_decorator.py

3 голосов
/ 02 апреля 2012

Атрибуты, которые вы ищете: __str__(), __repr__() и __unicode__().

1 голос
/ 11 июня 2012

Попробуйте использовать класс LazyString из stringlike , например

from stringlike.lazy import LazyString

def f(a, b):
    print("f called")
    return a+b

s = LazyString(lambda: f("a", "b"))
print("Starting")
print(s)
...