p149-

#封装:把属性和方法装起来
#广义:把属性和方法装起来,外面不能直接调用了,要通过类的名字调用
#狭义:把属性和方法藏起来,外面不能调用,只能内部调用,在定义属性前面加个双下划线(如:__pwd)
class User:
    __Country = 'China' #私有静态变量
    def __init__(self,name,password):
        self.name = name
        self.__pwd = password #私有实例变量

u1=User('tom','123456')
print(u1.__pwd) #AttributeError: 'User' object has no attribute '__pwd' #报错
#给一个变量前面加上双下划线的时候,这个名字变成私有
#所有的私有的内容或者名字都不能再类的外面调用,只能在类的内部使用
# #获取私有实例变量可以通过,类方法
class User:
    __Country = 'China' #私有静态变量
    def __init__(self,name,password):
        self.name = name
        self.__pwd = password #私有实例变量
    def get_pwd(self):
        return self.__pwd
u1=User('tom','123456')
print(u1.get_pwd()) #123456
# #如果非要改私有实力变量呢,也通过类的方法
class User:
    __Country = 'China' #私有静态变量
    def __init__(self,name,password):
        self.name = name
        self.__pwd = password #私有实例变量
    def get_pwd(self):
        return self.__pwd
    def change_pwd(self,new_pwd):
        self.__pwd = new_pwd
u1=User('tom','123456')
u1.change_pwd('111111')
print(u1.get_pwd())
#如果只返回加密后的密码 pwd
import hashlib
class User:
    __Country = 'China' #私有静态变量
    def __init__(self,name,password):
        self.name = name
        self.__pwd = password #私有实例变量
    def get_pwd(self):
        ret = hashlib.md5() #这里还可以用User的name加盐 ret = hashlib.md5(self.name.encode('utf-8'))
        # ret = hashlib.md5(self.name.encode('utf-8'))
        ret.update(self.__pwd.encode('utf-8'))
        return ret.hexdigest()
u1=User('tom','123456')
print(u1.get_pwd()) #e10adc3949ba59abbe56e057f20f883e
print(u1.get_pwd()) #f19b50d5e3433e65e6879d0e66632664   #加盐后的结果
#还可以做私有的方法,把加密的步骤写成私有的方法
import hashlib
class User:
    __Country = 'China' #私有静态变量
    def __init__(self,name,password):
        self.name = name
        self.__pwd = password #私有实例变量
    def __md5_pwd(self): #把方法私有化
        ret = hashlib.md5()  # 这里还可以用User的name加盐 ret = hashlib.md5(self.name.encode('utf-8'))
        # ret = hashlib.md5(self.name.encode('utf-8'))
        ret.update(self.__pwd.encode('utf-8'))
        return ret.hexdigest()
    def get_pwd(self):
        return self.__md5_pwd()
u1=User('tom','123456')
print(u1.get_pwd())  #e10adc3949ba59abbe56e057f20f883e
# print(u1.__md5_pwd()) #报错
#所有写在类里的都可以私有化
#私有变量为啥不能被外部调用?
class User:
    __Country = 'China'
    __hobby = 'Football' #在类的外部不能定义私有的概念
    def func(self):
        print(self.__Country) #在类的内部,自动把当前这句话所在的类名字拼接在私有变量,来完成变形
print(User._User__Country) #China
print(User._User__hobby) #Football
#私有内容能不能被子类使用? 不能
class Foo(object):
    def __init__(self):
        self.func()
    def func(self):
        print('in Foo')
class Son(Foo):
    def func(self):
        print('in son')
Son() #in son  实例化的时候 init 找父类 Foo ,然后init里面的func 是self调用的,就先从子类中找
class Foo(object):
    def __init__(self):
        self.__func() ##在类的内部,自动把当前这句话所在的类名字拼接在私有变量,来完成变形,这里self 虽然是Son实例化的对象
                      ##但是 在类的内部,自动把当前这句话所在的类名字拼接在私有变量上,来完成变形,__func变成_Foo__func
    def __func(self):
        print('in Foo')
class Son(Foo):
    def __func(self):
        print('in son')
Son() #in Foo


class Foo(object):
    def __func(self):
        print('in Foo')
class Son(Foo):
    def __init__(self):
        self.__func() #self调用__func()的时候是调用了 _Son__func ,但是子类中没有
Son() # 报错  AttributeError: 'Son' object has no attribute '_Son__func'
#在其他语言中的数据级别都有哪些?在python中有哪些
#public 公有的 类内类外都能用,父类子类都能用
#protect 保护的  类内能用,类外不行,父类子类都能用      python 不支持保护的
#private 私有的  本类的类内能用,其他地方不能用
#类的装饰器  property
#property
from math import pi
class Circle:
    def __init__(self,r):
        self.r = r
    @property #添加property装饰器,结尾就可以直接调用area方法 作为属性  把一个方法伪装成属性,调用的时候就不用加括号了
    def area(self):
        return self.r**2*pi
c1 = Circle(10)
print(c1.area)  #314.1592653589793
#被装饰的方法不能有参数
import time
class Person:
    def __init__(self,name,birth):
        self.name = name
        self.birth = birth
    @property
    def age(self):  #方法伪装成属性 ,另外这个方法不能有参数
        return time.localtime().tm_year-self.birth
p1 = Person('tom',1998)
print(p1.age) #22
#property的应用场景 : 和私有属性合作
class User:
    def __init__(self,name,pwd):
        self.name = name
        self.__pwd = pwd #把密码设置成私有变量,在下面伪装一个pwd方法为属性,就实现了,只能看,不能改的场景
    @property
    def pwd(self):
        return self.__pwd

u1 = User('tom','123456')
print(u1.pwd)
u1.pwd = 12111 #AttributeError: can't set attribute   不能改
#如果就想改变伪装的变量的私有属性
class Goods: #商品类
    def __init__(self,name,price):
        self.name = name
        self.__price = price
    @property
    def price(self):
        return self.__price
    @price.setter  #增加一个装饰器,结构为‘@被装饰函数名.setter’
    def price(self,new_price):
        self.__price = new_price
g1 = Goods('pen',5)
print(g1.price) #5
g1.price = 10
print(g1.price) #10
#这跟设置一个公共属性有什么区别,这里可以防止给属性非法赋值,比如 g1.price = ‘aaa’
#变更一下
class Goods: #商品类
    def __init__(self,name,price):
        self.name = name
        self.__price = price
    @property
    def price(self):
        return self.__price
    @price.setter  #增加一个装饰器,结构为‘@被装饰函数名.setter’
    def price(self,new_price):
        if isinstance(new_price,int):  #判断只有整数时才能赋值,否则没变化
            self.__price = new_price
g1 = Goods('pen',5)
print(g1.price) #5
g1.price = 'aa'  #不生效
print(g1.price) #5
posted on 2020-08-03 20:41  94小渣渣  阅读(76)  评论(0编辑  收藏  举报