Bound method, unbound method (static method), hidden property, property decorator

1, Binding method

  • Features: it should be called by whoever is bound to, and whoever calls it will pass it in as the first parameter

  • 1. If a function is defined in a class, it is bound to the object by default and should be called by the object. The object will be automatically passed in as the first parameter

  • 2. If you want to bind a function to a class, you need to use the method bound to the class: the method decorated with the classmethod decorator. The functions defined in the class are decorated with classmethod and bound to the class. They should be called by the class. Calling by the class will automatically pass in the class itself as the first parameter

There are two binding methods:
	1. Bound to object
    	class Student():
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    # When the method bound to the object is called by the object, it will pass itself as the first parameter to the function self
    def tell_info(self):
        print('name: %s,age:%s, gender:%s' % (self.name, self.age, self.gender))


        stu = Student('ly', 18, 'male')
        # print(stu.name)
        stu.tell_info() # stu.tell_info(stu)
    
    2. Bound to class
    	
class Mysql():
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    @classmethod  # This method is bound to a class. If a class calls it in the future, it will automatically pass the class name as the first parameter, cls
    def from_conf(cls):
        # cls => Oracle
        # obj = Oracle(settings.IP, settings.PORT)
        obj = cls(settings.IP, settings.PORT)
        return obj
 Mysql.from_conf()

2, Unbound method

  • Features: it is not bound to classes and objects, which means that anyone can call it, but no matter who calls it, it is an ordinary function without the effect of automatic parameter transfer

  • The function defined in the class is decorated with staticmethod and becomes an unbound method, that is, an ordinary function, which can be called by anyone. However, no matter who calls it, it is an ordinary function without the effect of automatic parameter transfer

    • Note: it is different from methods bound to objects. Functions directly defined in the class are bound to objects without any decorators. They are not ordinary functions. Objects call this method and automatically transfer values. Static method decorated methods, no matter who calls them, do not automatically transfer values

# It is neither bound to a class nor to an object
class Student():
    school = 'SH'
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @staticmethod  # Static method
    def create_id():
        import uuid
        return uuid.uuid4()

stu = Student('ly', 18)

# print(stu.create_id())
# print(Student.create_id())
print(stu.create_id())

3, How to hide attributes

  • In python, the attribute is hidden (set to private) by starting with a double underscore, but in fact, this is just a deformation operation

# 1. How to hide
		# 1. How to hide
'''
    1. In the class definition stage, syntactic deformation occurs_Class name__Attribute name
    2. Hide external misalignment
    3. Deformation occurs only in the class definition stage, and no deformation occurs in other cases

Why hide: The hidden attributes in the class can be used outside the class, but the purpose is not to use them outside the class. If you want to use them outside the class, open the interface inside the class for access
            It can achieve strict control over external data
'''
class Student():
    __school = 'SH' # _ Student__ school  => _ Class name__ Attribute name
    def __init__(self, name, age):
        self.__name = name
        self.age = age

    def __tell_info(self):  # _ Student__ tell_ info  => _ Class name__ Function name
        print('name: %s, age: %s' % (self.__name, self.age))

    def get_school(self):
        return self.__school  # self._Student__school

    def set_school(self, v):
        if type(v) is not str:
            print('Illegal data type')
        # if isinstance(v, str):
            return
        self.__school = v

# 2. Why hide attributes
# -Hide data properties in order to strictly control the operation of external visitors to the properties of the class
class People:

    def __init__(self,name,age):
        self.__name = name  # self._People__name = name
        self.__age = age

    def tell_info(self):
        print("<%s:%s>" %(self.__name,self.__age))

    def set_info(self,name,age):
        if type(name) is not str:
            print("Name must be a string")
            return
        if type(age) is not int:
            print("Age must be a number")
            return
        self.__name = name
        self.__age = age

obj1 = People("jack",18)  
obj1.tell_info()     # <jack:18>

obj1.set_info("tom",28)  
obj1.tell_info()     # <tom:28>

obj1.set_info(123123123123,28)  # Name must be a string
obj1.tell_info()     # <jack:18>

4, property decorator

Property is a special property. When you access it, you execute a function (function) and then return a value

Example 1: BMI index (BMI is calculated, but obviously it sounds like an attribute rather than a method. If we make it an attribute, it will be easier to understand)

BMI values for adults:

Too light: less than 18.5

Normal: 18.5-23.9

Overweight: 24-27

Obesity: 28-32

Very obese, above 32

Body mass index (BMI) = weight (kg) ÷ height ^ 2 (m)

  EX: 70kg÷(1.75×1.75)=22.86

class People:
    def __init__(self,name,weight,height):
        self.name = name
        self.weight = weight
        self.height = height
    @property
    def bmi(self):
        return self.weight / (self.height ** 2)

p1 = People('jack',75,1.8)

# print(p1.bmi())  # Parentheses are required for normal access to p1.bmi()
# 23.148148148148145

print(p1.bmi)    #  Use @ property to disguise the bmi function as a data property
# 23.148148148148145

1. Use of property

class People:
    def __init__(self,name):
        self.__name = name
        
        
#    def get_name(self):
#        return self.__name 

    @property            # 1. View behavior
    def name(self):      # The name function decorated with property is actually__ Name is hidden
        return self.__name

    @name.setter           # 
    def name(self,x):       # 2. Modification behavior
        if type(x) is not str:
            raise Exception("Name must be a string type")
        self.__name = x

    @name.deleter      # 3. Delete behavior
    def name(self):
        print("Deletion not allowed")

p1 = People('jack')
# print(p1.get_name)  # visit

# Corresponding view name behavior   
print(p1.name)   # p1.name self. Accessed through @ property__ Attribute of name

# Modify name behavior accordingly
p1.name = 123 # Throw exception
p1.name = "JACK"  # Normal modification
print(p1.name)

# Corresponding delete name behavior
del p1.name
print(p1.name)

# ps: with property, you can hide a property first__ The name attribute is hidden. After hiding, define three functions called name
#      In these three functions, the three behaviors of name 1, 2 and 3 are written respectively, which correspond to the operation one by one



# Understanding knowledge points: this method can also achieve the effect of the above operation

class People:
    def __init__(self,name):
        self.__name = name

    def get_name(self):
        return self.__name

    def set_name(self,x):
        if type(x) is not str:
            raise Exception("Name must be a string type")
        self.__name = x

    def del_name(self):
        print("Deletion not allowed")

    name = property(get_name,set_name,del_name)

p1 = People('jack')

Posted on Fri, 03 Dec 2021 10:40:51 -0500 by gregolson