2

In a python project I've been using static members of nested classes to store static configuration (e.g. table names for external data-stores and validation functions for data structures)

class a(object):
    foo = 1
    bar = 2

    class b(object):
        spam = "spam"

    class c(object):
        eggs = "eggs"

This allows me to quickly and easily get a config lookup, which my IDE (pycharm) can type/existence check and suggest auto-completions as I write code.

>>> a.b.spam
'spam'
>>> a.c.eggs
'eggs'

Suppose now, I want to add another nested class which refers to static members of a:

class a(object):
    foo = 1
    bar = 2

    class b(object):
        spam = "spam"

    class c(object):
        eggs = "eggs"

    class d(object):
        spams = "spam" * a.bar
        spam_and_eggs = a.b.spam + a.c.eggs

In a python console, this works as I'd like:

>>> a.d.spams
'spamspam'
>>> a.d.spam_and_eggs
'spameggs'

But putting the above into a .py file and running it as a module, I get name-errors:

Traceback (most recent call last):
  File "/usr/lib64/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib64/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/me/example/test.py", line 1, in <module>
    class a(object):
  File "/home/me/example/test.py", line 11, in a
    class d(object):
  File "/home/me/example/test.py", line 12, in d
    spams = "spam" * a.bar
NameError: name 'a' is not defined

Is there a combination of imports or a way I could solve this name-error? Alternatively is there a more pythonic way to implement this style of configuration which is free from this issue?

2
  • This seems an overly complicated approach. Wouldn't a named tuple work? Commented Jan 27, 2020 at 10:42
  • @StefOverflow I think that named tuples would make sense if I were using several different instantiations of the configuration and changing the schema infrequently. (To add a new branch, I'd need to define a new named-tuple-type and then make sure the instantiation stays in sync) In my use case, I only ever need one instance of the config, & I expect to change the code in the config relatively frequently. In my case, I think that the static-class nesting works neatly, because to add a new entry, I just add a new nested class to the tree, and hte shape and data of the tree stay together. Commented Jan 27, 2020 at 11:40

1 Answer 1

1

Would defining d after a and monkey-patching a be an option for you?

class a(object):
    foo = 1
    bar = 2

    class b(object):
        spam = "spam"

    class c(object):
        eggs = "eggs"


class d(object):
    spams = "spam" * a.bar
    spam_and_eggs = a.b.spam + a.c.eggs


a.d = d

print(a.d.spams)
# spamspam

I am not sure PyCharm will inspect this correctly, but at least the code would work.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.