Python 3.9 Initializing constants of class with static methods yields error

522 views Asked by At

I'm trying to create a class in python3.9 to dynamily load constant values of the class by loading a file from a static method as follows:

class SQLQueries(object):

    CLIPAPP = SQLQueries.load_query_statement('clinapp.sql')

    MENSALIDADES = SQLQueries.load_query_statement('mensalidades.sql')

    SINISTRO = SQLQueries.load_query_statement('sinistro.sql')


    @staticmethod
    def load_query_statement(sql_file, format_params=None):
        curr_dir = os.getcwd()
        sql_dir = os.path.join(curr_dir, 'queries', sql_file)
        with open(sql_dir, 'r') as sql:
            query = sql.read()
            query = query.format(format_params)
        return query

But when doing this, it yields the following error:

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-49-ddf4f8beb954> in <module>
----> 1 class SQLQueries(object):
      2 
      3     CLIPAPP = SQLQueries.load_query_statement('clinapp.sql')
      4 
      5     MENSALIDADES = SQLQueries.load_query_statement('mensalidades.sql')

<ipython-input-49-ddf4f8beb954> in SQLQueries()
      1 class SQLQueries(object):
      2 
----> 3     CLIPAPP = SQLQueries.load_query_statement('clinapp.sql')
      4 
      5     MENSALIDADES = SQLQueries.load_query_statement('mensalidades.sql')

NameError: name 'SQLQueries' is not defined

how can I fix that?

1

There are 1 answers

0
Masklinn On

how can I fix that?

By not doing it.

First, you're misunderstanding the execution model of Python in three ways:

  • Control flow aside, Python code executes linearly top to bottom
  • the "body" of a class statement is executed code, there's some magic surrounding the execution environment (the scope) but that's about it
  • the class object is not created until the class body has fully executed

In essence,

class Foo:
    ...

is syntactic sugar for:

def Foo_body():
    ...
    return locals()
Foo = type('Foo', (object,), Foo_body())

From this you can see two things:

  • It's impossible for a class body statement to refer to something following it in the class body
  • "methods" are nothing more than a bog-standard regular function until after the body has executed fully

Second, static methods are rarely if ever useful in Python, and as the old Python is not Java essay noted almost 20 years ago:

A static method in Java does not translate to a Python classmethod. [...] The idiomatic translation of a Java static method is usually a module-level function, not a classmethod or staticmethod.

So

  • if you're writing a staticmethod, you should not
  • if you're writing a classmethod, you should consider really hard whether that's actually needed e.g. you may need to override a non-default constructor (that's essentially the use-case)

Otherwise... just write a function. Functions are cool. Here you should just write a function, there is no reason for a staticmethod.

I'm not sure the class itself is even useful, frankly.