一、封装
# 面向对象的三大特性 : 继承 多态 封装# 封装 : # 广义上的 # 狭义上的 :会对一种现象起一个专门属于它的名字 # 把一堆东西装在一个容器里 # 函数和属性装到了一个非全局的命名空间 —— 封装# class A:# __N = ‘aaa‘ # 静态变量## print(A.__N) # python# pulic 公有的# private 私有的 # java完全面向对象的语言# public 公有的# protect 保护的# private 私有的 # 定义一个私有的名字 : 就是在私有的名气前面加两条下划线 __N = ‘aaa‘# 所谓私有,就是不能在类的外面去引用它# class A:# __N = ‘aaa‘ # 静态变量# def func(self):# print(A.__N) # 在类的内部使用正常## a = A()# a.func()# print(A.__N) # 在类的外部直接使用 报错 # class A:# __N = ‘aaa‘ # 静态变量# def func(self):# print(A.__N) # 在类的内部使用正常## print(A.__dict__)# print(A._A__N) # python就是把__名字当成私有的语法 # 一个私有的名字 在存储的过程中仍然会出现在A.__dict__中,所以我们仍然可以调用到。# python对其的名字进行了修改: _类名__名字# 只不过在类的外部调用 :需要“_类名__名字”去使用# 在类的内部可以正常的使用名字 # _A__N# 在类内 只要你的代码遇到__名字,就会被python解释器自动的转换成_类名__名字 # 私有的属性# class B:# def __init__(self,name):# self.__name = name# def func(self):# print(‘in func : %s‘%self.__name)# b = B(‘alex‘)# # print(b._B__name)# b.func() # 私有的方法# class C:# def __wahaha(self):# print(‘wahaha‘)# def ADCa(self):# self.__wahaha()# c = C()# # c._C__wahaha()# c.ADCa() # 在类中,静态属性,方法,对象属性都可以变成私有的,只需要在这些名字之前加上__ # class D:# def __func(self): # ‘_D__func‘# print(‘in func‘)## class E(D):# def __init__(self):# self.__func() # ‘_E__func‘# e = E()# 私有的名字不能被子类继承 # class D:# def __init__(self):# self.__func()# def __func(self):# print(‘in D‘)## class E(D):# def __func(self):# print(‘in E‘)# e = E()# 私有的名字,在类内使用的时候,就是会变形成_该类名__方法名# 以此为例 :没有双下换线会先找E中的func# 但是有了双下划线,会在调用这个名字的类D中直接找_D__func # class F:# pass# F.__name = ‘alex‘ # 不是在创建私有属性# print(F.__name)# print(F.__dict__)# 变形只在类的内部发生 # class F:# def ADCa(self):# self.__name = ‘alex‘ # _F__name## f = F()# f.ADCa()# print(f._F__name) # java中的对比# public 公有的 在类的内部可以使用,子类可以使用,外部可以使用 python中所有正常的名字# protect 保护的 在类的内部可以使用,子类可以使用,外部不可以使用 python中没有# private 私有的 只能在类的内部使用,子类和外部都不可以使用 python中的__名字 # 私有的用法# 当一个方法不想被子类继承的时候# 有些属性或者方法不希望从外部被调用,只想提供给内部的方法使用 # 描述一个房子 # 单价 # 面积 # 长宽高# class Room:# def __init__(self,name,price,length,width,height):# self.name = name# self.price = price# self.__length = length# self.__width = width# self.__height = height## def area(self):# return self.__length*self.__width # r = Room(‘鹏鹏‘,100,2,1,0.5)# print(r.name)# print(r.price)# print(r.area()) # class Person:# def __init__(self,name,pwd):# self.name = name# self.__pwd(pwd)# def __pwd(self,pwd):# # ‘12345‘ ---> ascii ---> 2175981070935# self.my_secret_pwd = 2175981070935 二、property方法:
# 人体BMI指数# 体质指数(BMI)=体重(kg)÷身高^2(m)# 写一个类 描述人体BMI指数 class Person: def __init__(self,name,weight,height): self.name = name self.__height = height self.__weight = weight # self.bmi = self.__weight / self.__height ** 2 # self.bmi = self.cal_BMI() def cal_BMI(self): return self.__weight / self.__height ** 2 @property def bmi(self): return self.__weight / self.__height ** 2p = Person(‘大表哥‘,92,1.85)# print(p.cal_BMI())# p.cal_BMI() # bmi是一个名词# print(p.bmi) # bmi是一个名词# p._Person__weight = 90# print(p.bmi)# 将一个方法伪装成一个属性 # 并不会让你的代码有什么逻辑上的提高 # 只是从调用者的角度上换了一种方式,使之看起来更合理 # 单纯的在init中计算# class Person:# def __init__(self,name,weight,height):# self.name = name# self.__height = height# self.__weight = weight# self.bmi = self.__weight / self.__height ** 2## p = Person(‘大表哥‘,92,1.85) ## print(p.bmi) # bmi是一个名词# p._Person__weight = 90 # 3天# print(p.bmi) # class Person:# def __init__(self,name,weight,height):# self.name = name# self.__height = height# self.__weight = weight# @property# def bmi(self):# return self.__weight / self.__height ** 2## p = Person(‘大表哥‘,92,1.85)# print(p.bmi)# p._Person__weight = 90# print(p.bmi) # @property 能够将一个方法伪装成一个属性# 从原来的的对象名.方法名(),变成了对象名.方法名# 只是让代码变的更美观 # 如果有重名的名字# class Person:# def __init__(self,name,weight,height):# self.name = name# self.__height = height# self.__weight = weight# @property# def bmi(self):# return self.__weight / self.__height ** 2# print(Person.__dict__)# p = Person(‘大表哥‘,92,1.85)# print(p.__dict__)# print(p.bmi) # 对这个属性 只能看了 # 被property装饰的bmi仍然是一个方法 存在Person.__dict__# 对象的.__dict__中不会存储这个属性 # 在一个类加载的过程中,会先加载这个中的名字,包括被property装饰的# 在实例化对象的时候,python解释器会先到类的空间里看看有没有这个被装饰的属性,# 如果有就不能再在自己对象的空间中创建这个属性了 # 圆形类# 半径 面积 周长# from math import pi# class Circle:# def __init__(self,r):# self.r = r# def cal_area(self):# return self.r**2*pi# def cal_perimeter(self):# return 2*pi*self.r# c = Circle(10)# print(c.cal_area())# print(c.cal_perimeter()) # 将方法伪装成属性,方法中一般涉及的都是一些计算过程# from math import pi# class Circle:# def __init__(self,r):# self.r = r# @property# def area(self):# return self.r**2*pi## @property# def perimeter(self):# return 2*pi*self.r# c = Circle(10)# print(c.area)# print(c.perimeter)# c.r = 15# print(c.area)# print(c.perimeter) # __name setter deleter# class Person0:# def __init__(self,name):# self.name = name## p = Person0(‘alex‘)# print(p.name)# p.name = ‘sb‘# p.name = 123 # class Person:# def __init__(self,name):# self.__name = name # 私有的属性了# @property# def name(self):# return self.__name## def set_name(self,new_name):# if type(new_name) is str:# self.__name = new_name# else:# print(‘您提供的姓名数据类型不合法‘)## p = Person(‘alex‘)# print(p.name)# # 和直接定义name属性有什么区别???# p.set_name(‘alex_sb‘)# print(p.name)# p.set_name(123)# print(p.name) # 方法伪装成的属性的修改# class Person:# def __init__(self,n):# self.__name = n # 私有的属性了# @property# def name(self):# return self.__name## @name.setter # 重要程度 ***# def name(self,new_name):# if type(new_name) is str:# self.__name = new_name# else:# print(‘您提供的姓名数据类型不合法‘)## p = Person(‘alex‘)# print(p.name) #def name(self):# p.name = ‘alex_sb‘ #def name(self,new_name):# print(p.name) #def name(self):# p.name = 123 #def name(self,new_name):# print(p.name) #def name(self): # 方法伪装成的属性的删除class Person: def __init__(self,n): self.__name = n # 私有的属性了 @property # 重要程度 **** def name(self): return self.__name # @name.deleter # def name(self): # print(‘name 被删除了‘) # @name.deleter # 重要程度* # def name(self): # del self.__name # p = Person(‘alex‘)# print(p.name)# del p.name # 只是执行了被@name.deleter装饰的函数# print(p.name) #@property --> func 将方法伪装成属性,只观看的事儿#@func.setter --> func 对伪装的属性进行赋值的时候调用这个方法 一般情况下用来做修改#@func.deleter --> func 在执行del 对象.func的时候调用这个方法 一般情况下用来做删除 基本不用 # 商品的 折扣# 有一个商品 : 原价 折扣# 当我要查看价格的时候 我想看折后价# class Goods:# def __init__(self,name,origin_price,discount):# self.name = name# self.__price = origin_price# self.__discount = discount## @property# def price(self):# return self.__price * self.__discount# @price.setter# def price(self,new_price):# if type(new_price) is int or type(new_price) is float:# self.__price = new_price# apple = Goods(‘apple‘,5,0.8)# print(apple.price)# # 修改苹果的原价# apple.price = 8# print(apple.price) # 将一些需要随着一部分属性的变化而变化的值的计算过程 从方法 伪装成属性# 将私有的属性保护起来,让修改的部分增加一些约束,来提高程序的稳定性和数据的安全性 三、@classmethod方法和@staticmethod方法
# 店庆 全场八折class Goods: __discount = 0.8 def __init__(self,name,origin_price): self.name = name self.__price = origin_price @property def price(self): return self.__price*self.__discount @classmethod def change_discount(cls,new_discount): cls.__discount = new_discountGoods.change_discount(1)a = Goods(‘apple‘,8)b = Goods(‘banana‘,6)print(a.price)print(b.price) # 折扣变了 店庆结束 恢复折扣# apple.change_discount(1) # 如果要改变折扣 是全场的事情 不牵扯到一个具体的物品 所以不应该使用对象来调用这个方法# print(apple.price)# print(banana.price) # staticmethod# 当一个方法要使用对象的属性时 就是用普通的方法# 当一个方法要使用类中的静态属性时 就是用类方法# 当一个方法要既不使用对象的属性也不使用类中的静态属性时,就可以使用staticmethod静态方法 # def login():# user= input(‘user :‘)# if user == ‘alex‘:print(‘success‘)# else :print(‘faild‘)## login()class Student: def __init__(self,name):pass @staticmethod def login(a): # login就是一个类中的静态方法 静态方法没有默认参数 就当成普通的函数使用即可 user = input(‘user :‘) if user == ‘alex‘: print(‘success‘) else: print(‘faild‘) Student.login(1) # 完全面向对象编程# 先登录 后 实例化# 还没有一个具体的对象的时候 就要执行login方法 # 使用什么样的方法要看具体用到了哪些名称空间中的变量 # 当一个方法要使用对象的属性时 就是用普通的方法 # 当一个方法要使用类中的静态属性时 就是用类方法 # 当一个方法要既不使用对象的属性也不使用类中的静态属性时,就可以使用staticmethod静态方法
原文地址:https://www.cnblogs.com/zzw731862651/p/8868365.html
时间: 2024-07-31 12:03:38