一、封装:
1、广义上面向对象的封装:代码的保护,面向对象的思想本身就是一种封装
2、只让自己的对象能调用自己类的方法
3、狭义上的封装 – 面向对象三大特性
4、属性和方法都藏起来,不让你看见
class Person:
def __init__(self,name,passwd):
self.name = name
self.__passwd = passwd #加上双下划线后会变成私有属性,只在类的内部可以使用
def __get_pwd(self): #加上双下划线后会变成私有方法
return self.__passwd #只要在类的内部使用私有属性,就会自动带上类名
long = Person('longlong','1234') #long.passwd,long.__passwd都调不到
print(long.__dict__)
print(long._Person__passwd) #_long.Person__passwd可以调到,但是是你在投机取巧的方式下知道的方式
print(long.get_pwd())
输出结果:
{‘name’: ‘longlong’, ‘_Person__passwd’: ‘1234’}
1234
1234
(1)所有的私有 都是在变量的左边加上双下划线
对象的私有属性
类的私有方法
类中的静态私有属性
所有的私有的都不能在类的外部使用
class Room:
def __init__(self,name,length,wideth):
self.name = name
self.__length = length
self.__wideth = wideth
def set_name(self,newName):
if type(newName) is str and newName.isdigit() == False:
self.__name = newName
def get_name(self):
return self.__name
def area(self):
return self.__length*self.__wideth
long = Room('龙龙',10,10)
print(long.area())
long.set_name('2')
print(long.get_name())
输出结果:
100
Traceback (most recent call last):
File “D:/Python/python_txt/GUI进度条/GUI.py”, line 1258, in
print(long.get_name())
File “D:/Python/python_txt/GUI进度条/GUI.py”, line 1252, in get_name
return self.__name
AttributeError: ‘Room’ object has no attribute ‘_Room__name’
2、假设父类的私有属性能被子类调用会用到私有的这个概念的场景
(1).隐藏起一个属性,不想让类的外部调用
(2).我想保护这个属性,不能让属性随意被改变
(3).我想保护这个属性不被子类继承
@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 pi*self.r**2
c1 = Circle(5)
print(c1.area)
print(c1.perimeter)
输出结果:
78.53981633974483
31.41592653589793
class Person:
def __init__(self,name,high,weight):
self.name = name
self.high = high
self.weight = weight
@property
def bmi(self):
return self.weight/self.high**2
long = Person('龙',1.83,75)
print(long.bmi)
输出结果:
22.395413419331717
class Person:
def __init__(self,name):
self.__name = name
@property
def name(self): #一般不能有参数
return self.__name + 'sb'
@name.setter #实现对隐藏对象修改,只能传一个参数
def name(self,new_name):
self.__name = new_name
geng= Person('耿')
print(geng.name)
geng.name = '娃'
print(geng.name)
耿sb
娃sb
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
apple = Goods('苹果',5)
print(apple.price)
4.0
@属性的查看 修改 删除
class Person:
def __init__(self,name):
self.__name = name
@property
def name(self):
return self.__name
@name.deleter
def name(self): #删除
del self.__name
@name.deleter
def name(self,new_name): #修改
self.__name = new_name
geng = Person('耿娃')
print(geng.name)
del geng.name
geng.name('娃')
print(geng.name)
输出结果:
耿娃
Traceback (most recent call last):
File “D:/Python/python_txt/GUI进度条/GUI.py”, line 1333, in
print(geng.name)
File “D:/Python/python_txt/GUI进度条/GUI.py”, line 1326, in name
return self.__name
AttributeError: ‘Person’ object has no attribute ‘_Person__name’
3、classmethod #类方法
@当这个方法的燥作只涉及静态属性的时候,就应该使用class_method来装饰这个方法
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)
print(apple.price)
输出结果:
4.0
2.5
4、staticmethod #静态方法
在完全面向对象的程序中,如果一个的数既和对象没有关系也和类没有关系那么就用staticmethod将这个函数变成一个静态方法
class Login:
def __init__(self,name,password):
self.name = name
self.pwd = password
def login(self):
pass
@staticmethod
def get_usr_pwd(): #没有默认参数,就像函数一样
usr = input('用户名:')
pwd = input('密码:')
Login(usr,pwd)
Login.get_usr_pwd()