Created
July 30, 2012 01:39
-
-
Save jtratner/3203215 to your computer and use it in GitHub Desktop.
Injecting global imports/locals
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# In an actual use case, pkg1 and pkg2 would be packages, | |
# but to make this runnable I used classes | |
# to make a namespace instead (same idea regardless) | |
# make a dummy class so we can use it as a namespace | |
class Dummy(object): pass | |
pkg1, pkg2 = Dummy(), Dummy() | |
pkg1.average = lambda *args : sum(args) * 1.0 / len(args) | |
pkg2.get_lengths = lambda *args : map(len, args) | |
### Use defaults with boolean or to set locals | |
# (this gets *really* long with many local variables) | |
def get_average_class(**kwargs): | |
# note that if you used average = kwargs.get("average") or average here | |
# you'd get an error about using an unbound local. | |
# (and using globals would kinda defeat the purpose entirely) | |
average = kwargs.get("average") or pkg1.average | |
get_lengths = kwargs.get("get_lengths") or pkg2.get_lengths | |
class AverageList(object): | |
def __init__(self, *args): | |
self.items = args | |
@property | |
def average(self): | |
return average(*get_lengths(*self.items)) | |
return AverageList | |
adjusted_lengths = lambda *args: map(len, args) + [15] | |
print (get_average_class())([1,2], [10, 4, 5, 6]).average == 3 # True | |
print (get_average_class(get_lengths=adjusted_lengths))([1,2], [10, 4, 5, 6]).average == 7 # True | |
# This example shows how you *can't* add to the locals dict | |
average = pkg1.average | |
get_lengths = pkg2.get_lengths | |
def get_average_class2(**kwargs): | |
# this doesn't work because adding to localvars does nothing | |
localvars = locals() | |
for k in ("average", "get_lengths"): | |
if kwargs.get(k, None): | |
localvars[k] = kwargs[k] | |
class AverageList2(object): | |
def __init__(self, *args): | |
self.items = args | |
@property | |
def average(self): | |
return average(*get_lengths(*self.items)) | |
return AverageList2 | |
adjusted_lengths = lambda *args: map(len, args) + [15] | |
print (get_average_class2())([1,2], [10, 4, 5, 6]).average == 3 # True | |
print (get_average_class2(get_lengths=adjusted_lengths))([1,2], [10, 4, 5, 6]).average == 7 # False |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment