python--面向对象:封装

广义上面向对象的封装 :代码的保护,面向对象的思想本身就是一种
只让自己的对象能调用自己类中的方法
狭义上的封装 ——> 面向对象的三大特性之一
属性 和 方法都藏起来 不让你看见
"""
会用到私有的这个概念de场景
1.隐藏起一个属性 不想让类的外部调用
2.我想保护这个属性,不想让属性随意被改变
3.我想保护这个属性,不被子类继承
"""
应用场景
class Person:
    __key = 123  # 私有静态属性
    def __init__(self,name,passwd):
        self.name = name
        self.__passwd = passwd   # 私有属性

    def __get_pwd(self):         # 私有方法
        return self.__passwd   #只要在类的内部使用私有属性,就会自动的带上_类名

    def login(self):          # 正常的方法调用私有的方法
        self.__get_pwd()

alex = Person('alex','alex3714')
print(alex._Person__passwd)   # _类名__属性名
print(alex.get_pwd())   #这种会报错
print(alex._Person__get_pwd())
# 所有的私有 都是在变量的左边加上双下划綫
    # 对象的私有属性
    # 类中的私有方法
    # 类中的静态私有属性
# 所有的私有的 都不能在类的外部使用

 二、封装与扩展性:对象可以调用类方法和静态方法么? 可以 但一般情况下 推荐用类名调用

有一道题是这样的
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,new_name):
        if type(new_name) is str and new_name.isdigit()==False:
            self.__name=new_name
        else:
            print('名字修改不合法')
    def area_room(self):
        return self.__length * self.__width
my_room=Room('my_room',100,100)
print(my_room.get_name())     #my_room
print(my_room.set_name('big_room'))        #big_room
print(my_room.area_room())    #10000
View Code
1.property:
是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值,内置装饰器函数 只在面向对象中使用
先看一个简单一点的用法:
from math import pi
class Circle:
    def __init__(self,r):
        self.r = r
    @property
    def perimeter(self):
        return 2*pi*self.r
    @property
    def area(self):
        return self.r**2*pi

c1 = Circle(5)
print(c1.area)     # 圆的面积     #表明上可以省掉一个调用 的括号
print(c1.perimeter) # 圆的周长
View Code
如果用property装饰一下上面的例题,会怎么样呢?已然变成了进阶版
class Room:
    def __init__(self,name,length,width):
        self.__name = name
        self.__length = length
        self.__width = width
    @property                      #在每个方法都装饰这个函数,那么在下面调用的时候就可以把方法伪装为属性调用啦
    def name(self):
        return self.__name

    @name.setter                    #这里为了实现对neme的修改,所以用name.setter这个装饰,并且方法名要和被修改的name保持一致
    def name(self,new_name):
        if type(new_name) is str and new_name.isdigit()==False:     #判断修改的新名字是字符串并且不是数字,才能允许修改
            self.__name=new_name    #这里要修改的是私有属性name 所以要加上双下划线
        else:
            return '名字修改不合法'
    @name.deleter                    #装饰删除name
    def name(self):
        del self.__name
    @property                    #普通装饰作用
    def area_room(self):
        return self.__length * self.__width
my_room=Room('my_room',100,100)
print(my_room.name)     #my_room
my_room.name='big_room'
print(my_room.area_room)     #10000
print(my_room.name)        #big_room
del my_room.name   #删除了,如果再打印my_room.name会报错的
#计算圆的周长和面积
from math import pi
class Circle:
    def __init__(self,r):
        self.c_r=r
    @property
    def perimeter(self):
        return 2*self.c_r*pi
    @property
    def area(self):
        return pi*self.c_r**2
circle_1=Circle(3)
print(circle_1.perimeter)
print(circle_1.area)
#计算体脂数
class Person:
    def __init__(self,high,weigh):
        self.high=high
        self.weigh=weigh
    @property
    def BMI(self):
        return self.weigh/self.high**2
zzy=Person(1.58,51)
print(zzy.BMI)
property练习
为什么要用property:
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,
这种特性的使用方式遵循了统一访问的原则
2.method 方法:
classmethod   类方法    ****   当方法操作值涉及静态属性,传cls  进行类的操作,而不是传self 就用classmethod
class Goods:
    __discount = 0.8
    def __init__(self,name,price):
        self.name = name
        self.__price = price
    @property
    def price(self):
        return self.__price * Goods.__discount
    @classmethod   # 把一个方法 变成一个类中的方法,这个方法就直接可以被类调用,不需要依托任何对象
    def change_discount(cls,new_discount):  # 修改折扣 默认传cls
        cls.__discount = new_discount
apple = Goods('苹果',5)
print(apple.price)
Goods.change_discount(0.5)   # Goods.change_discount(Goods)
apple.change_discount(0.7)     #3.5不推荐使用对象调用
print(apple.price)
# 当这个方法的操作只涉及静态属性的时候 就应该使用classmethod来装饰这个方法
staticmethod  静态的方法 *** 
:在完全面向对象的程序中,
如果一个函数 既和对象没有关系 也和类没有关系 那么就用staticmethod将这个函数变成一个静态方法
当想写纯面向对象中写一个和类和对象无关的函数时候,不想默认传self 这时候用staticmethod
class Staticmethod_Demo():
    role = 'dog'

    @staticmethod
    def func():                        #()里面可以任意写参数,不用默认写self
print("当普通方法用") Staticmethod_Demo.func()
staticmethod练习

三、小结

# 类方法和静态方法 都是类调用的
# 对象可以调用类方法和静态方法么?   可以   但一般情况下 推荐用类名调用
# 类方法 有一个默认参数 cls 代表这个类  cls
# 静态方法 没有默认的参数 就象函数一样

原文地址:https://www.cnblogs.com/zzy-9318/p/8324143.html