IntroI warmly invite you to speculate on the output of the following program: Class A (object): Def __init__ (self): Self.__private () Self.public ( def __private (self): print ' A.__private () ' Def public (self): print ' A.public () ' Class B (A): def __private (self): print ' B.__private () ' Def public (self): print ' B.public () ' B = B ()
Preliminary study onThe correct answer is: A.__private () b.public () If you have guessed right, you can not read my blog. If you do not guess right or have doubts in mind, then my Bo Wenzheng is prepared for you. It all starts with why the "a.__private ()" is exported. But to be clear about why, we need to know the naming mechanism for Python. According to Python manual, the variable name (identifier) is an atomic element of Python. When the variable name is bound to an object, the variable name refers to the object, just like human society, isn't it. When the variable name appears in the code block, it is the local variable, and when the variable name appears in the module, it is the global variable. The module believes everyone has a good understanding, but the code block can be confusing. Here's an explanation: the code block is a piece of Python program text that can act as an executable unit, and modules, function bodies, and class definitions are blocks of code. Not only that, each interactive script command is also a code block; a script file is also a block of code; A command-line script is also a block of code. Then we'll talk about the visibility of variables, and we'll introduce a range of concepts. The scope is the visibility of the variable name in the code block. If a local variable is defined in a code block, the scope includes the code block. If the variable is defined in a block of functional code, the scope extends to any block of code in the function block unless it defines another variable with the same name. However, the scope of the variables defined in the class is limited to the class code block and not extended to the method code block.
missingAccording to the theory in the last section, we can divide the code into three blocks: the definition of Class A, the definition of Class B, and the definition of variable B. Based on the class definition, we know that the code defines three member variables for Class A (the Python function is also an object, so the member method is called a member variable and it makes sense.) Class B defines two member variables. This can be verified by the following code: >>> print ' \ n '. Join (dir (A)) _a__private __init__ public >>> print ' \ n '. Join (dir (B)) _a__ Private _b__private __init__ Public, why Class A has a name for the _a__private Attribute it. and the __private disappeared. This is going to talk about Python's proprietary variable rolling down.
Explore A friend who knows Python knows that Python takes a variable that starts with two or more underscore characters and has no two or an underscore ending as a private variable. Private variables are converted to long format (public) before code is generated. The conversion mechanism is this: Insert the class name at the front of the variable, and then add an underscore character to the front end. This is called the private variable rolling pressure (private name mangling). The __private identifier in class A will be converted to _a__private, which is why the _a__private and __private disappeared in the previous section. Another two point: one is because the rolling pressure will make the identifier longer, when more than 255, Python will cut off, pay attention to the resulting naming conflict. Second, when the class name is all underlined, Python no longer performs rolling. such as: >>> class ____ (object): def __init__ (self): Self.__method () def __method (self): print ' ____.__method () ' >> > print ' \ n '. Join (dir (___)) __class__ __delattr__ __dict__ __doc__ __getattribute__ __hash__ __init__ __method # has not been rolled __module__ __new__ __reduce__ __ reduce_ex__ __repr__ __setattr__ __str__ __weakref__ >>> obj = ___ () ____.__method () >>> Obj.__method () # can be called Externally ____.__method () Now let's look back and see why the "A.__private ()" is being exported.
Truth I believe the wise reader has guessed the answer now. If you haven't thought of it, I'll give you a hint: the truth is similar to the macro preprocessing in C language. Because Class A defines a private member function (a variable), you perform a private variable rolling before the code is generated (note that there is no line in the previous section marked red). )。 After rolling, the code for Class A becomes like this: Class A (object): def __init__ (self): self._a__private () # This line has changed self.public () def _a__private (self): # This line has changed print ' a.__private () ' def public (self): print ' a.public () ' is not a bit like the C language in the macro expansion AH. Because the __init__ method is not overridden when class B is defined, the call is still a.__init__, that is, the self._a__private () is executed, and the natural output "a.__private ()" is made. The following two pieces of code can increase persuasion and enhance understanding: >>> class C (A): &nbsP def __init__ (self): # rewrite __init__, no longer invoke self._a__private self.__private () # This is bound to _c_private Self.public () def __private (self): print ' c.__private () ' def public (self): print ' c.public () ' >>> C = C () c.__ Private () C.public () ############################ >>> class A (object): def __init__ (self): self._a__private () # Call an undefined function, Python will give it to my Self.public () def __private (self): print ' a.__private () ' def public (self): print ' A.public () ' >>>a = A () a.__private () A.public ()
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.