Discussion on the read and write permissions of python object data

  • 2020-05-10 18:29:04
  • OfStack

Object-oriented programming languages are often easier and safer to use when writing large programs than process-oriented languages. The first reason is the class mechanism.

Class, to classify and encapsulate numerous data, so that a data object becomes a complete individual, close to the real life, highly abstract. However, python does not encapsulate the class well, because all the properties and methods are exposed, you can access or write to them at will, and you can modify or even add properties to the class outside of the class. It's really unsettling.

The following is a summary of 1 after learning the solution.

1, use 2 underscore prefixes to hide properties or methods.


__xxx

#!/usr/bin/python3
#-*- coding:utf-8 -*-


class Student:
  def __init__(self,name,score):
    self.name = name
    self.__score = score # will score Hide it so that it is only available within the class. 

  def __show(self):    #1 Three hidden methods, again only available internally 
    print(self.name,self.__score)# Use the hidden properties __score
    
  def Show(self):
    self.__show()    # Notice how the hidden method is called. 


  
def main():
  he = Student('Bob',95)
  he.Show()       # Display: Bob 95
  #print(he.__score)   #AttributeError: 'Student' object has no attribute '__score'
  #he.__show()      #AttributeError: 'Student' object has no attribute '__show'

  # Are hidden properties really hidden? You can still use it, use the format  obj._className__attributeName
  # However, just for the sake of understanding, the use of hidden properties is not recommended. 
  print(he._Student__show())  # Display: Bob 95
  print(he._Student__score)   #  Display:  95
  
  
  

if __name__=="__main__":
  main()

Effect of double underlining on class attributes:

1. Make the property only used for the internal, external and subclass of this class can not be directly read and modified.

2. The properties of the class using __ will be changed in the implementation, such as s = s = s = s = s = s = s = s = s = s = s = s = s = s = s = s = s = s = s = s = s. This avoids being overridden by subclass attributes.

2. Create manageable properties.

Sometimes we need to do extra checks on property writes, reject illegal values, and throw exceptions.


#!/usr/bin/python3
#-*- coding:utf-8 -*-


class Student:
  def __init__(self,name,score):
    self.name = name
    self.score = score 

  @property        # Implement the property of the read method, read the instance score This function is called when the 
  def score(self):
    return self.__score

  
  @score.setter     # Implement property write method, write to the instance score Property, this function is called 
  def score(self,newVal):
    if not isinstance(newVal,(int,float)):
      raise TypeError('score value must be a number')
    if newVal>100 or newVal<0:
      raise ValueError('score value must between 0 and 100')

    self.__score = newVal

  

  
def main():
  he = Student('Bob',95)
  he.score = 100   # To write  

  
  print(he.score)  # read    
    
  

if __name__=="__main__":
  main()

We can find that   self.s. S 31en is the actual place to store the property values, while self.s. 33en is the function (only it works like a property), which is the method of getting and writing the property values.

The socre.setter decorated function will also be called during initialization, as the call of self.score appears under the s 38en__ () function

S: since self. S 44en is only used to refer to the value of the property, can you use another name? Such as saveScore... Sure, but it "exposes" and we don't want it to be available externally, so it should

Add and hide it to prevent accidental modification.

Sometimes, when you are sure that a class is not involved in inheritance, you can rewrite the double underscore as a single slider. This will not have the hidden effect, but: 1.

Avoid making a mountain out of a molehill. On the other side, start with an underscore to remind the user that this attribute should not be used directly. Well, it depends on self-awareness.

1 instance object can be externally added at will.


#!/usr/bin/python3
#-*- coding:utf-8 -*-


class Student:
  def __init__(self,name,score):
    self.name = name
    self.score = score 

 

  
def main():
  he = Student('Bob',95)
  he.age = 19
  print(he.age)
  

if __name__=="__main__":
  main()

 use __slots__



#!/usr/bin/python3
#-*- coding:utf-8 -*-


class Student:
  __slots__ = ('name','score') # Adds the property name to the tuple as a string 
  def __init__(self,name,score):
    self.name = name
    self.score = score 

 

  
def main():
  he = Student('Bob',95)
  he.age = 19  #AttributeError: 'Student' object has no attribute 'age'
  print(he.age)
  

if __name__=="__main__":
  main()

Thus, the properties of the object are limited within the class.

But s 60en __ cannot be inherited. Moreover, the design of s61en__ is not intended to use this method, but instead to optimize the memory usage for creating large Numbers of objects.

Conclusion:

As I write, I find that the above technique makes little sense. The design of the class is the programmer himself, the user is also himself, so, the properties of the object

You should read and write on your own, and the class design itself does not require much protection code, which can be bloated and inefficient. The protection should take place outside the class, so that the data received by the class object is always legal, which makes it easier and more flexible. That's how I feel.


Related articles: