封装

1,封装:就相当于把一件物品装进袋子封起来
2,在封装的基础上,我们可以将装到对象或者类中的属性给隐藏起来
注意:
1)在定义类或者初始化对象时,在属性前加__,就会将该属性赢藏起来
但该隐藏起始只是一种变形_类名__属性名,并没有真的隐藏起来

2)该变形操作是在定义阶段扫描语法时发生的变形,类定义之后添加的__开头的属性不会发生变形

3)该隐藏是对外不对内的

4)在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的

例1:

class Student:
   __school = 'oldboy'

   def __init__(obj,x,y,z):
      obj.name = x
      obj.age = y
      obj.gender = z

​      def __choose(self):
​         print('%s 正在选课' % self.name)


stu_obj1 = Student('冯小寒',18,'male')
stu_obj1.__x = 111
print(stu_obj1.__dict__)
print(stu_obj1.__x)

print(stu_obj1.__dict__)
print(stu_obj1._Student__name)

print(Student.__dict__)
print(Student._Student__school)
print(stu_obj1.Student__school)

隐藏属性的意义何在:
1,把数据属性隐藏起来的意义是:在类中开放接口,让外界使用者通过接口来操作属性值,我们可以在接口之上附加任意的逻辑
来严格控制外界使用者对属性的操作

class Student:
   __school = 'oldboy'

   def __init__(obj,x,y,z):
      obj.__name = x
      obj.age = y
      obj.gender = z

   def __choose(self):
      print('%s 正在选课'%self.__name)

   def get_name(self):
      print(self.__name)

   def set_age(self,x):
      if type(x) is not int:
         print('年龄必须是整数')
         return
      self.__age = x

   def get_age(self):
      print(self.__age)

   def del_age(self):
      del self.__age

stu_obj1 = Student('冯小涵',18,'male')
stu_obj1.get_name()
print(stu_obj1.__dict__)

2,把功能属性隐藏起来:隔离复杂度

class ATM:
    def __card(self):
        print('插卡')
    def __auth(self):
        print('用户认证')
    def __input(self):
        print('输入取款金额')
    def __print_bill(self):
        print('打印账单')
    def __take_money(self):
        print('取款')

​    def withdraw(self):
​        self.__card()
​        self.__auth()
​        self.__input()
​        self.__print_bill()
​        self.__take_money()

a=ATM()
a.withdraw()

property装饰器:
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

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('liu', 72, 1.78)
print(p1.bmi)

例二:

class Student:
   __school = 'oldboy'

   def __init__(obj, x, y, z):
      obj.__name = x
      obj.__age = y
      obj.gender = z

   def get_name(self):
      print('访问控制')
      return self.__name

   def set_name(self, x):
      print('赋值控制')
      self.__name = x

   def del_name(self):
      print('删除控制')
      del self.__name

   def get_age(self):
      return self.__age

   def set_age(self,x):
      if type(x) is not int:
         print('年龄必须是整形')
         return
      self.__age = x
   def del_age(self):
      print('不让删')

   age = property(get_age,set_age,del_age)
   name = property(get_name(),set_name,del_name)

stu_obj1 = Student("冯疯子", 18, "female")

# print(stu_obj1.age)

# stu_obj1.age = "19"

# del stu_obj1.age

# print(stu_obj1.age)


print(stu_obj1.name)

# stu_obj1.name="EGON"

# del stu_obj1.name

例三:

class Student:
   __school = 'oldboy'

   def __init__(obj,x,y,z):
      obj.__name = x
      obj.__age = y
      obj.gender = z

   @property
   def name(self):
      print('访问控制')
      return self.__name

   @name.setter
   def name(self,x):
      print('赋值控制')
      self.__name = x

   @name.deleter
   def name(self):
      print('删除控制')
      del self.__name

stu_obj1 = Student('冯子涵',17,'male')

stu_obj1.name

类中定义的函数
1,绑定方法:谁来调用就会将谁当做第一个参数传入
1)绑定给对象的方法:类中定义的函数默认就是绑定给对象的方法,应该由对象调用,会把对象当做第一个参数传入
2)绑定给类的方法:在类中的函数加上一个装饰器@classmethod,该函数就绑定给类了,应该由类来调用,会把类当做的哥参数传入

2,非绑定方法:即不与类绑定也不与对象绑定,就是一个普通的函数,谁都可以来调用,没有自动传参的效果
在函数上添加装饰器@staticmethod

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

   def tell_info(self):
      print('%s:%s'%(self.name,self.age))

   @classmethod
   def f1(cls):
      print(cls)

   @staticmethod
   def f2(x,y,z):
      print(x,y,z)

p1 = People('liu',17)

p1.tell_info()

print(p1.tell_info)
print(People.f1)
print(p1.f2)
p1.f2(1,2,3)
People.f2(1,2,3)

例2:

import uuid
import setting

class MySQL:
   def __init__(self,ip,port):
      self.mid = self.__create_id()
      self.ip = ip
      self.port = port

   def tell_info(self):
      print("%s:<%s:%s>" %(self.mid,self.ip,self.port))

   @staticmethod
   def __create_id():
      return uuid.uuid4()

   @classmethod
   def from_conf(cls):
      return cls(setting.IP,setting.PORT)

obj1 = MySQL.from_conf()
obj1.tell_info()