Hi
How can I run the function from function name?

Here what I have and it gives me an ERROR. Can someone explain why and how to fix it.

Thanks

ContantsGlobal.py

CMD = ["02", "A0"]

Test.py

import ConstantsGlobal as GCONST

class Test(object):
    def __init__(self):
        self.__dic = dict(("0x"+f, "self.__CMD"+f) for f in GCONST.CMD)

    def runCmd(self):
        func = getattr(self, self.__dic["0x02"]) # even if I add eval(self.__dic["0x02"]) -> Not Working
        func()

    def __CMD02(self):
        print "02"

    def __CMDA0(self):
        print "A0"


if __name__ == "__main__":
    t = Test()
    t.runCmd()

--
Mark

The first problem is that you are using attributes starting with double underscores. Double underscores are used by the interpreter to simulate "private" attributes (which don't really exist in the language). So if you set an attribute __dic , the instance will actually have an attribute _Test__dic instead of __dic . The same applies to the member functions __CMD02 and __CMDA0. So getattr(self, "__CMD02") won't work.

The simpler solution is that you avoid private attributes and write a single underscore at the beginning of the "hidden" attributes.

Edited 5 Years Ago by Gribouillis: n/a

Wow thank you Gribouillis, that works perfectly.

Now is there a way to force it to call private functions? Because I'm calling private function through another member function. So why self.__CMD02() works but not with getattr() function?


Thanks Again

--
Mark

Edited 5 Years Ago by markfw: n/a

Wow thank you Gribouillis, that works perfectly.

Now is there a way to force it to call private functions? Because I'm calling private function through another member function. So why self.__CMD02() works but not with getattr() function?


Thanks Again

--
Mark

I think it's because when the compiler transforms your code into bytecode, it changes self.__CMD02() into self._Test__CMD02() in a member function. This is not done in a call to getattr(). You could add the class name by hand in your getattr like in getattr(self, "_Test__CMD%s" % f) .

My advice is to avoid private methods. They are not "pythonic" and they add no value to your code. If you really need to ensure that a method is not called with a subclass' instance (which is rarely needed), you can simply add an assert statement like this

class Test(object):
    def myprivatemethod(self):
        assert type(self) is Test # or self.__class__ is Test
        ...

Edited 5 Years Ago by Gribouillis: n/a

Thanks, everything is now clear.

Thanks a lot


--
Mark

This article has been dead for over six months. Start a new discussion instead.