2

i have trouble accessing a static member of a class. the simplest example of my use-case is:

class A:
    _tmpl = '<{}>'
    print(_tmpl)
    VAR = tuple(_tmpl.format(var) for var in ('a', 'b'))

this prints <{}> as it should from the print statement; but the line with the tuple raises the exception:

NameError: name '_tmpl' is not defined

what is happening here? how can i fix it (A._tmpl will not work either...).

hiro protagonist
  • 44,693
  • 14
  • 86
  • 111
  • use `A._tmpl` instead of `_tmpl`. – Sraw Feb 13 '18 at 09:15
  • 1
    nope; `A` is not yet (fully) defined. that does not work: `AttributeError: type object 'A' has no attribute '_tmpl'` (should have added that to the question...) – hiro protagonist Feb 13 '18 at 09:16
  • 2
    The workaround is to simply do it after the class declaration: `A.VAR = tuple(... A._tmpl ...)` – deceze Feb 13 '18 at 09:18
  • @deceze thanks for the workaround! could you explain what i am missing? why can i access `_tmpl` in the `print` statement but not inside `tuple`? ...ok, the dupe explains it all. thanks! – hiro protagonist Feb 13 '18 at 09:20
  • @hiroprotagonist Yes, I realized that later. – Sraw Feb 13 '18 at 09:22
  • 2
    This is a consequence of the way that class block scope works, it is a special case, that doesn't create an enclosing scope, however, that means that comprehension constructs, which essentially use a function scope, cannot access variables in the class block's namespace, the same way a method couldn't access `_tmpl ` without `A. _tmpl`, *but inside the class body `A` doesn't exist yet* – juanpa.arrivillaga Feb 13 '18 at 09:22
  • @juanpa.arrivillaga thanks a lot! and thanks for the duplicate. great answer there! – hiro protagonist Feb 13 '18 at 09:23
  • 1
    @hiroprotagonist make sure to check out both, both answers have a lot of good info – juanpa.arrivillaga Feb 13 '18 at 09:24
  • 1
    Also, relevant section in the docs: https://docs.python.org/3/reference/executionmodel.html#resolution-of-names – juanpa.arrivillaga Feb 13 '18 at 09:25
  • After watching discussion, I found a solution: `VAR = tuple(inspect.currentframe().f_back.f_locals.get("_tmpl").format(var) for var in ('a', 'b'))`. It is not pythonical but works. – Sraw Feb 13 '18 at 09:28
  • @Sraw yeah, sometimes you should just use a for-loop... – juanpa.arrivillaga Feb 13 '18 at 09:40

0 Answers0