自学Python之路-django

一、封装

1.1  封装概念

广义上面向对象的封装 :代码的保护,面向对象的思想本身就是一种封装,只让自己的对象调用自己的方法。

狭义上的封装:面向对象的三大基本特征之一,隐藏对象的属性和实现细节,仅对外提供公共访问方式。

封装的好处: 

  • 将变化隔离; 
  • 便于使用;
  • 提高复用性; 
  • 提高安全性;

封装原则:

  • 将不需要对外提供的内容都隐藏起来;
  • 把属性都隐藏,提供公共方法对其访问。
class Person:
    def __init__(self,name,passwd):
        self.name = name
        self.passwd = passwd
carlos = Person("carlos","carlos7628")
print(carlos.passwd)  # 打印出carlos的密码

自学Python5.7-面向对象三大基本特征_封装

1.2  私有属性

1.2.1  私有属性,在外部调用不到

# 若不想别人查看carlos的密码
class Person:
    def __init__(self,name,passwd):
        self.name = name
        self.__passwd = passwd   #加上"__",隐藏属性,----私有属性
carlos = Person("carlos","carlos7628")
print(carlos.__passwd)

自学Python5.7-面向对象三大基本特征_封装

1.2.2  私有属性,使用一种方法可以在外部调用(通常不使用)

class Person:
    def __init__(self,name,passwd):
        self.name = name
        self.__passwd = passwd   #加上"__",隐藏方法
carlos = Person("carlos","carlos7628")
print(carlos.__dict__)  # 查看属性里面都有什么

自学Python5.7-面向对象三大基本特征_封装

此时查看到密码的真实属性是“_Person__passwd'”, 再来print一下:

class Person:
    def __init__(self,name,passwd):
        self.name = name
        self.__passwd = passwd   #加上"__",隐藏方法
carlos = Person("carlos","carlos7628")
print(carlos._Person__passwd)  # _类的名字__属性的名字,就能查看到私有属性的内容

自学Python5.7-面向对象三大基本特征_封装

1.2.3  私有属性,只要在类的内部使用私有属性,就会自动的转换成带上_类名

class Person:
    def __init__(self,name,passwd):
        self.name = name
        self.__passwd = passwd   #加上"__",隐藏方法 ,
    def get_pwd(self):
        return self.__passwd    #只要在类的内部使用私有属性,就会自动的转换成带上_类名。 就是_Person__passwd
carlos = Person("carlos","carlos7628")
print(carlos._Person__passwd)
print(carlos.get_pwd())

自学Python5.7-面向对象三大基本特征_封装

1.2.4  只要在类的内部使用私有属性,就会自动的转换成带上_类名,就是_Person__passwd。但是在类的外部不是的。

class Person:
    def __init__(self,name,passwd):
        self.name = name
        self.__passwd = passwd   #加上"__",隐藏方法
    def get_pwd(self):
        print(self.__dict__)
        return self.__passwd    #只要在类的内部使用私有属性,就会自动的转换成带上_类名
carlos = Person("carlos","carlos7628")
print(carlos._Person__passwd)
carlos.__high = 181
print(carlos.get_pwd())
print(carlos.__high)

自学Python5.7-面向对象三大基本特征_封装

举例:

# 定一个房子类, 计算面积
class Room:
    def __init__(self,name,length,width):
        self.name = name
        self.__length = length     #私有属性
        self.__width = width       #私有属性
    def area(self): 
        return self.__length * self.__width
Tong = Room('Tong',2,1)
print(Tong.area())

自学Python5.7-面向对象三大基本特征_封装

现在有个问题,如果更改name,使用方法如下:

class Room:
    def __init__(self,name,length,width):
        self.name = name
        self.__length = length
        self.__width = width
    def area(self):
        return self.__length * self.__width
Tong = Room('Tong',2,1)
print(Tong.area())
Tong.name = "Carlos"
print(Tong.name)

自学Python5.7-面向对象三大基本特征_封装

最好的解决办法如下,name采用私有属性。 (对私有属性的保护,不可以随便更改名字name)

class Room:
    def __init__(self,name,length,width):
        self.__name = name
        self.__length = length
        self.__width = width
    def get_name(self):
        return self.__name
    def set_name(self,newName):
        if type(newName) is str and newName.isdigit() == False:   # 非数字的字符串
            self.__name = newName
        else:
            print('不合法的姓名')
    def area(self):
        return self.__length * self.__width
Tong = Room('Tong',12,6)
print(Tong.area())       # 打印tong房子的面积
Tong.set_name("carlos")  # 设置名字为carlos
print(Tong.get_name())    
Tong.set_name("2")     # 设置了非法的名字2
print(Tong.get_name())

自学Python5.7-面向对象三大基本特征_封装

1.2.5 父类的私有属性不能被子类调用

# 父类的私有属性不能被子类调用
class Foo:
    __key = '123'       # _Foo__key   静态私有属性

class Son(Foo):
    print(Foo.__key)     # _Son__key

自学Python5.7-面向对象三大基本特征_封装

1.3  私有方法

class Person:
    def __init__(self,name,passwd):
        self.name = name
        self.__passwd = passwd   #加上"__",隐藏方法
    def __get_pwd(self):         #私有方法
        return self.__passwd    #只要在类的内部使用私有属性,就会自动的转换成带上_类名
    def login(self):          # 正常的方法调用私有的方法
        self.__get_pwd()

1.4  总结

  • # 所有的私有 都是在变量的左边加上双下划綫
  •    对象的私有属性
  •    类中的私有方法
  •    类中的静态私有属性
  • # 所有的私有的 都不能在类的外部使用
  • # 采用私有概念的场景:①隐藏起一个属性 ,不想让类的外部调用;②我想保护这个属性,不想让属性随意被改变;③我想保护这个属性,不被子类继承

、property内置函数

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

举例1:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)

成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖, 高于32
  体质指数(BMI)=体重(kg)÷身高^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('carlos',75,1.85)
print(p1.bmi)  # @Property直接调用属性bmi====== 没有Property调用方法bmi()

自学Python5.7-面向对象三大基本特征_封装

举例2: 圆的面积和周长

from math import pi
class Circle:
    def __init__(self,r):
        self.r = r
    def permeter(self):
        return 2*pi*self.r
    def area(self):
        return self.r**2*pi
c1 = Circle(5)
print(c1.permeter())  #圆的周长
print(c1.area())      #圆的面积

自学Python5.7-面向对象三大基本特征_封装

from math import pi
class Circle:
    def __init__(self,r):
        self.r = r
    @property
    def permeter(self):
        return 2*pi*self.r
    @property
    def area(self):
        return self.r**2*pi
c1 = Circle(5)
print(c1.permeter)  #圆的周长,可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
print(c1.area)      #圆的面积

自学Python5.7-面向对象三大基本特征_封装

注意:此时的特性area和perimeter不能被赋值。

 1 from math import pi
 2 class Circle:
 3     def __init__(self,r):
 4         self.r = r
 5     @property
 6     def permeter(self):
 7         return 2*pi*self.r
 8     @property
 9     def area(self):
10         return self.r**2*pi
11 c1 = Circle(5)
12 c.area=3    #为特性area赋值
此时特性area和perimeter不能被赋值

相关文章:

  • 2021-05-21
  • 2022-01-28
  • 2021-08-09
  • 2022-01-15
  • 2021-12-16
  • 2021-10-16
  • 2021-09-26
  • 2022-12-23
猜你喜欢
  • 2021-06-03
  • 2022-01-15
  • 2021-08-20
  • 2021-06-30
  • 2021-10-18
  • 2021-11-30
相关资源
相似解决方案