day 封装,面向对象,@property @classmethod @staticmethod方法

Posted zzw731862651

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了day 封装,面向对象,@property @classmethod @staticmethod方法相关的知识,希望对你有一定的参考价值。

一、封装

# 面向对象的三大特性 : 继承 多态 封装
# 封装 :
# 广义上的
# 狭义上的 :会对一种现象起一个专门属于它的名字

# 把一堆东西装在一个容器里

# 函数和属性装到了一个非全局的命名空间 —— 封装
# 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 ** 2
p = 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_discount
Goods.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静态方法
































以上是关于day 封装,面向对象,@property @classmethod @staticmethod方法的主要内容,如果未能解决你的问题,请参考以下文章

day19-面向对象之封装property特性绑定与非绑定

day_25 面向对象

面向对象之封装 及@property装饰器使用

Python学习 Day13 Python 面向对象学习2:@property多重继承

python面向对象:组合封装property装饰器多态

面向对象三大特性——封装(含property)