3

I wonder why it's not possible to use eval() function on the private attributes.

class A:
    def __init__(self):
        __private = 5
        print(__private + 2)  # Prints '7'
        print(eval('__private + 2'))  # NameError: name '__private' is not defined

A()
Miłosz
  • 69
  • 4
  • 1
    Don't use a double leading underscore. – Passerby Nov 15 '21 at 13:46
  • Does this answer your question? [What is the meaning of single and double underscore before an object name?](https://stackoverflow.com/questions/1301346/what-is-the-meaning-of-single-and-double-underscore-before-an-object-name) – Passerby Nov 15 '21 at 13:50
  • 3
    Interesting. So "private" variables are name mangled with the class name ([doc](https://docs.python.org/3/tutorial/classes.html#private-variables)). `print(eval('_A__private + 2'))` seems to work. But `__private` is not a class level variable, is it? – 001 Nov 15 '21 at 13:55
  • 1
    @JohnnyMopp The doc says _" without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class"_, so it is mangled. It looks like the `eval` has a separate scope or something like that. – VPfB Nov 15 '21 at 14:40

1 Answers1

2

It's related to the name mangling, see the documentation:

Notice that code passed to exec() or eval() does not consider the classname of the invoking class to be the current class; this is similar to the effect of the global statement, the effect of which is likewise restricted to code that is byte-compiled together. The same restriction applies to getattr(), setattr() and delattr(), as well as when referencing __dict__ directly.

So, to properly use a private variable in eval(), it has to be passed in a mangled form, e.g. print(eval('_A__private + 2'))

funnydman
  • 9,083
  • 4
  • 40
  • 55