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

Recommended Answers

All 4 Replies

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.

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

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
        ...

Thanks, everything is now clear.

Thanks a lot


--
Mark

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.