Initialize a Python Constant Using a Function Declared After It
Question: I'm used to writing the following piece of code in Java or C# without errors.
It allows me to centralize the conversion of string to a floating point
representation. Unlike the simple implementation below, I have a lot more
going on in there to handle commas or brackets for negative numbers in Excel.

I can understand why Python gives an error. Python code is not compiled but
interpreted in sequence and `toFloat` does not exist for Python while its
processing the declaration of `ZERO` .

I was wondering if there is a pythonic way of doing this without having to
pull the `toFloat` function to another module OR without having to not declare
`ZERO` at the very top?

    
    
    ZERO = toFloat('0.0')    # <-- ERROR on this line "Undefined variable: toFloat"
    
    def toFloat(val):
        """Function to convert a string to a float"""
        return Decimal(val)
    


Answer: You are accessing an undefined symbol, which is a bad idea in many languages.
Python has no idea, what the symbol `toFloat` might refer to.

For illustration, what would you expect this code to do? Should `ZERO` be zero
or one?

    
    
    ZERO = toFloat('0.0')
    
    def toFloat(val): return Decimal(val)
    def toFloat(val): return 1
    

Or in this case:

    
    
    ZERO = toFloat('0.0')
    
    if ZERO: from libone import toFloat #where toFloat returns 0
    else: from libtwo import toFloat #where toFloat returns 1
    

The thing is you can redefine your symbols as many times you want. E.g. this
is legit code:

    
    
    def f(): return 0
    print(f())
    def f(): return 1
    print(f())
    

* * *

If it is of vital importance that `ZERO` be declared at the top of your code,
maybe you can use this ugly hack for your constants:

Put this in another file, let's say const.py:

    
    
    class Constant:
        def __init__(self, cf):
            self.cf = cf
    
        @property
        def c(self):
            try: return self.__c
            except: self.__c = self.cf()
            return self.__c
    

And then in your file, you can use:

    
    
    from const import Constant
    
    ZERO = Constant(lambda: toFloat('0.0'))
    def toFloat(x): return 42
    print(ZERO.c)
    

