In python it is valid to use an import
statement inside a class to define class variables that are just stolen from other modules:
class CustomMath:
from math import pi
assert isinstance(CustomMath.pi, float) # passes
It is also valid to refer to a global variable to the class with the very confusing statement x=x
x = 1
class Test:
# this loads the global variable x and stores in in the class scope
x = x
assert Test.x == 1 # passes
However if I am using a function to generate classes is there a similar way to copy a variable from the function arguments to the class body?
I want something of this nature:
def generate_meta_options(model, design):
class Meta:
# copy the nonlocal variable model to this scope
# but this isn't valid syntax
model = (nonlocal model)
design = translate_old_design_spec_to_new_format((nonlocal design))
return Meta
The parameter name matters because it is being passed by keyword not by order generate_meta_options(design="A", model=Operation)
and the name in the class has to be the same, I have found a work around by making variable aliases to all of the inputs but this is kind of annoying
def generate_meta_options_works(model, design):
_model = model
_design = design
class Meta:
model = _model
design = translate_old_design_spec_to_new_format(_design)
return Meta
Is there a better way of achieving this using the nonlocal
keyword? It seems that python does allow nonlocal
and global
to be used in a class but the variables are not retained in the class so I can't imagine a use case for it.
gl = 'this is defined globally'
def nonlocal_in_class_test():
lo = 'this is defined locally'
class Test:
nonlocal lo
global gl
lo = 'foo'
gl = 'bar'
assert lo == 'foo' # passes
assert gl == 'bar' # passes
assert hasattr(Test, 'lo') or hasattr(Test, 'gl'), 'lo nor gl was put in the class scope' # fails
I'm sure the library I'm using just needs an object with attribute lookup so I could move away from classes but every example I've seen uses classes (I suspect because inheriting multiple configs is natural) so I am hesitant to go that route.
It seems really odd that it is easier to copy a variable from a different module than it is to copy one right in the above scope so I thought I'd ask, is there a way to copy a variable from a nonlocal
scope into a class attribute without creating a separate variable with a distinct name?
As a tangent is there any case where using the nonlocal
or global
keywords inside a class body is useful? I assume it is not useful but there is also no reason to do extra work to disallow it.