net*_*vah 5 python variables lazy-evaluation
我想创建仅在我真正需要时才初始化变量的代码。但是以常规方式初始化:
var = None
if var is None:
var = factory()
var2 = var
Run Code Online (Sandbox Code Playgroud)
在代码中制造太多噪音。
我试图创建快速解决方案,但我觉得有更好的选择。这是我的快速解决方案,但无法获取参数并为此使用 defaultdict。
def lazy_variable(factory):
data = defaultdict(factory)
return lambda: data['']
var = lazy_variable(a_factory)
var2 = var()
Run Code Online (Sandbox Code Playgroud)
更多问题:
编辑:
请考虑性能。我知道我可以创建一个可以具有这种行为的类,但它比简单的解决方案和默认的 dict 解决方案慢。
尝试一些解决方案:
定义:
import cachetools.func
import random
@cachetools.func.lru_cache(None)
def factory(i):
return random.random()
Run Code Online (Sandbox Code Playgroud)
并运行:
%%timeit
for i in xrange(100):
q = factory(i)
q = factory(i)
Run Code Online (Sandbox Code Playgroud)
得到了:
100 loops, best of 3: 2.63 ms per loop
Run Code Online (Sandbox Code Playgroud)
幼稚的:
%%timeit
for i in xrange(100):
a = None
if a is None:
a = random.random()
q = a
q = a
Run Code Online (Sandbox Code Playgroud)
得到了:
The slowest run took 4.71 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 14.8 µs per loop
Run Code Online (Sandbox Code Playgroud)
我不确定缓存了什么
默认字典解决方案:
%%timeit
for i in xrange(100):
a = lazy_variable(random.random)
q = a()
q = a()
Run Code Online (Sandbox Code Playgroud)
得到了:
The slowest run took 4.11 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 76.3 µs per loop
Run Code Online (Sandbox Code Playgroud)
天啊!
好吧,我想我找到了一个使用生成器的又好又快的解决方案:
def create_and_generate(creator):
value = creator()
while True:
yield value
def lazy_variable(creator):
generator_instance = create_and_generate(creator)
return lambda: next(generator_instance)
Run Code Online (Sandbox Code Playgroud)
另一个快速解决方案是:
def lazy_variable(factory):
data = []
def f():
if not data:
data.extend((factory(),))
return data[0]
return f
Run Code Online (Sandbox Code Playgroud)
但我认为生成器更清晰。