1

I want to create a python class to encapsulate some global variables:

class TestEnvironment(object):
    _on_out = None
    # ...

    @staticmethod
    def onOut():
        return TestEnvironment._on_out

    @staticmethod
    def setOnOut(on_out):
        TestEnvironment._on_out = on_out

# -------------------------------------------------------------------- #

def log(msg, process = None):
    print msg

# -------------------------------------------------------------------- #

if __name__ == '__main__':
    TestEnvironment.setOnOut(log)
    print log
    print TestEnvironment.onOut()    
    TestEnvironment.onOut()("A test")

When running I get:

<function log at 0x7fd7738122a8>
<unbound method TestEnvironment.log>
...
TypeError: unbound method log() must be called with TestEnvironment instance as first argument (got str instance instead)

Seems that when I set log into TestEnvironment it became unbound method.

How can I overpass it?

Elad Weiss
  • 3,662
  • 3
  • 22
  • 50
  • 1
    This only happens in Python 2; you should really upgrade. – Daniel Roseman Jan 18 '18 at 12:22
  • Try the @staticmethod decorator for `log` too? – Nishant Jan 18 '18 at 12:22
  • 1
    In a nutshell: because of how class properties are returned via `__get__` according to the descriptor protocol: https://docs.python.org/2/howto/descriptor.html – deceze Jan 18 '18 at 12:23
  • 1
    Note that this wouldn't happen if you created a `TestEnvironment` instance and converted `setOnOut` to be a normal instance method. – Kos Jan 18 '18 at 13:19

1 Answers1

1

EDIT:

Removed my answer is it is no longer relevant (question seem to have changed). Either way - running your code on Python 3.6 seem to work:

Python 3.6.1 (default, Dec 2015, 13:05:11)
[GCC 4.8.2] on linux

<function log at 0x7f2787e0a488>
<function log at 0x7f2787e0a488>
A test

Here is a way to get it to work in Python 2.7:

def onOut():
    return TestEnvironment.__dict__['_on_out']

Check out this question

Eytan Avisror
  • 2,860
  • 19
  • 26