一、封装:
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
-
所有的私有 都是在变量的左边加上双下划线
对象的私有属性
类的私有方法
类中的静态私有属性
所有的私有的都不能在类的外部使用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’ -
假设父类的私有属性能被子类调用会用到私有的这个概念的场景
(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.41592653589793class 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
娃sbclass 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’ -
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 -
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()