py -- access restrictions

Inside the Class, there can be attributes and methods, while external code can operate data by directly calling the methods of instance variables. In this way, the internal complex logic is hidden.

However, from the previous definition of Student class, external code can freely modify the name and score attributes of an instance:

>>> bart = Student('Bart Simpson', 59)
>>> bart.score
59
>>> bart.score = 99
>>> bart.score
99

If you want the internal attribute not to be accessed externally, you can prefix the name of the attribute with two underscores _, In Python, if the variable name of the instance is__ At the beginning, it becomes a private variable, which can only be accessed internally, but not externally. Therefore, we change the Student class:

class Student(object):

    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))

After the modification, there is no change to the external code, but the instance variables cannot be accessed from the outside__ name and instance variables__ score:

>>> bart = Student('Bart Simpson', 59)
>>> bart.__name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__name'

This ensures that the external code cannot modify the internal state of the object at will, so that the code is more robust through the protection of access restrictions.

But what if the external code wants to get name and score? You can add get to the Student class_ Name and get_score method:

class Student(object):
    ...

    def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score

What if you want to allow external code to modify the score? You can add set to the Student class_ Score method:

class Student(object):
    ...

    def set_score(self, score):
        self.__score = score

You might ask, the original way to go directly through Bart Score = 99 can also be modified. Why does it take so much trouble to define a method? Because in the method, you can check the parameters to avoid passing in invalid parameters:

class Student(object):
    ...

    def set_score(self, score):
        if 0 <= score <= 100:
            self.__score = score
        else:
            raise ValueError('bad score')

Note that in Python, variable names are similar__ xxx__ , that is, those that start with double underscores and end with double underscores, are special variables. Special variables can be accessed directly, not private variables. Therefore, they cannot be used__ name__,__ score__ Such variable names.

Sometimes, you will see instance variable names starting with an underscore, such as_ name, such instance variables can be accessed externally. However, according to the Convention, when you see such variables, it means, "although I can be accessed, please treat me as a private variable and don't access it at will".

Are instance variables that begin with double underscores necessarily inaccessible from the outside? Not really. Not directly accessible__ Name is because the Python interpreter__ The name variable has been changed to_ Student__name, so you can still pass_ Student__name to access__ Name variable:

>>> bart._Student__name
'Bart Simpson'

However, it is strongly recommended that you do not do so, because different versions of Python interpreters may__ Change name to a different variable name.

In general, Python itself has no mechanism to prevent you from doing bad things. It all depends on self-consciousness.

Finally, pay attention to the following incorrect writing:

>>> bart = Student('Bart Simpson', 59)
>>> bart.get_name()
'Bart Simpson'
>>> bart.__name = 'New Name' # Set__ name variable!
>>> bart.__name
'New Name'

On the surface, the external code is "successfully" set up__ Name variable, but actually this__ Name variable and class internal__ The name variable is not a variable! Internal__ The name variable has been automatically changed by the Python interpreter to_ Student__name, and the external code adds a new one to bart__ Name variable. If you don't believe me, try:

>>> bart.get_name() # get_name() internally returns self__ name
'Bart Simpson'

Tags: Python

Posted by immobilarity on Tue, 03 May 2022 08:06:31 +0300