__xxx
。双下划线开头的属性,是对象的隐藏属性,隐藏属性只能在类的内部访问,无法通过对象访问。_累名__属性名
,例如__name ——>_Person__name
(这种方式实际上依然可以在外部访问,但是这种方式我们一般不用。一般我们会将一些私有属性以单下划线开头)class Car:
def __init__(self, name, color):
self.name = name
self.color = color
def run(self):
print('汽车开始跑了')
def horn(self):
print('BIBIBIBIKBI')
car = Car('法拉利','红色')
# print(car.name, car.color)
car.name = '小猫咪'
print(car.name,car.color)
car.run()
car.horn()
打印输出结果:
汽车开始跑了
BIBIBIBIKBI
分析:上述代码应该输出
小猫咪 红色
汽车开始跑了
BIBIBIBIKBI
但是为car实例添加的属性为小猫咪时,小猫咪的这恶搞属性就覆盖了法拉利。
这样就打乱了这一类的代码。导致错误。
class Dog:
def __init__(self, name):
self.hidden_name = name
dog = Dog('哈士奇')
# print(dog.hidden_name)
dog.name = '田园犬'
print(dog.hidden_name)
打印输出结果:
哈士奇
分析:使用这种方式过于简单,只是简单的对哈士奇进行了封装,田园犬这个属性没有对哈士奇这个属性产生影响。
class Car():
def __init__(self, name, color):
# 属性名称 值
# 这种方式告诉别人这个是私有属性,不要轻易修改
# __name 叫做完全封装 私有属性
self.__name = name
self.__color = color
def run(self):
print('汽车开始跑了')
def laba(self):
print('滴滴滴')
# getter方法 setter方法
# getter方法用查看私有属性 如果只有一个getter方法,没有setter方法:这个属性是一个只读属性
def get_name(self):
return self.__name
# setter方法是用来修改私有属性
def set_name(self, name):
self.__name = name
car = Car('奔驰', '黑色')
# _类名__属性名
# print(car._Car__name)
# car.__name = '雪佛兰' 这种方式是外行 没有工作经验的程序员
print(car.get_name())
# print(car.set_name('宝马'))
print(car.get_name())
打印输出结果:
E:\python\python.exe D:/PycharmProjects/基础班第11期/day-13/上课代码/01-封装.py
奔驰
奔驰
Process finished with exit code 0
分析:首先,在代码内部定义出了读取方法和修改方法,就证明,该代码内部的封装属性是可以修改的。
总结: 封装确实增加了类的定义的负责程度,但是也保证了数据的安全。
class Person:
def __init__(self, name):
self._name = name
# getter()--查看属性方法:(可读)
def getter_name(self):
print('用户调用了此读取方法')
return self._name
# setter()--修改属性方法:(可写)
def setter_name(self, name):
print('用户调用了此修改方法')
self._name = name
p1 = Person('陈慧翎')
p1.setter_name('周慧敏')
# print(p1._name) # 未调用get方法禁止查看属性
# p1.name = '黄一琳'
# print(p1.name)
print(p1.getter_name())
打印输出结果:
用户调用了此修改方法
用户调用了此读取方法
周慧敏
总结: 封装确实增加了类的定义的负责程度,但是也保证了数据的安全。
class Person:
def __init__(self, name):
self._name = name
@property # 设置只读属性(与getter方法类似)
def name(self):
print('getter方法执行了')
return self._name
@name.setter # 代表setter方法
def name(self, name):
print('setter方法执行了')
self._name = name
p1 = Person('周慧敏')
p1.name = '黄一琳'
print(p1.name)
打印输出结果:
setter方法执行了
getter方法执行了
黄一琳
总结:首先通过装饰器设置只读属性,再通过装饰器设置setter可修改属性,就可以告诉其他的同事,这是一个封装的参数,如果需要修改请通过正当方式修改。
class Animal():
def sleep(self):
print('动物会睡觉')
def run(self):
print('动物会跑')
# 定义一个狗类
# 1. 直接在动物类上面修改 违反ocp
# 2. 创建一个新的类(狗类) 会出现大量重复的代码
# 3. 直接从动物类中间拿到属性和方法 (推荐)=> 继承:就是在定义类名之后的括号里写上继承的父类(超类)
class Dog(Animal):
pass
dog = Dog()
dog.run()
dog.sleep()
# 检测是否是类创建的实例对象
res = isinstance(dog, Dog)
print(res)
# 检测是否是当前类的父类 issubclass
res = issubclass(Dog, Animal)
print(res)
# object 是所有类的父类
res = issubclass(Animal, object)
print(res)
打印输出结果:
E:\python\python.exe D:/PycharmProjects/基础班第11期/day-13/上课代码/04-继承的使用.py
动物会跑
动物会睡觉
True
True
True
Process finished with exit code 0
class A(object):
def test(self):
print('A.....')
class B(A):
def test(self):
print('B......')
class C(B):
def test(self):
print('C......')
c = C()
c.test()
# 方法的重写: 子类重写父类的方法,会将父类中的方法所覆盖掉 发扬光大的作用才会重写方法
打印输出结果:
E:\python\python.exe D:/PycharmProjects/基础班第11期/day-13/上课代码/06-关于方法的重写.py
C......
Process finished with exit code 0
总结:方法的重写就是子类覆盖父类的方法。
class Animal(object):
def __init__(self, name):
self._name = name
def sleep(self):
print('动物会睡觉')
def run(self):
print('动物会跑')
def get_name(self):
print('get 方法调用了')
return self._name
class Dog(object):
def __init__(self, gender):
self.gender = gender
class Zhonghua(Animal, Dog):
def __init__(self, age, name, gender):
super().__init__(gender)
super().__init__(name)
self.gender = gender
self._name = name
self.age = age
def sleep(self):
super().sleep()
print('狗会睡觉')
def run(self):
print('狗会跑')
dog = Zhonghua('中华田园犬', 18, '男')
dog.sleep()
# print(dog.get_name())
print(type(Zhonghua))
print(issubclass(Zhonghua, type))
print(issubclass(type, object))
# 解耦合 1. 提高问题的解决概率 2. 提高问题的解决效率 3. 提高解决问题的速度 4. 降低爆发隐患的可能性
# 多重继承: 兄弟类中都有相同的方法,那么先调用写到前面的那个类的方法
打印输出结果:
E:\python\python.exe D:/PycharmProjects/基础班第11期/day-13/上课代码/05-super方法及其使用.py
动物会睡觉
狗会睡觉
<class 'type'>
False
True
Process finished with exit code 0
总结:通过supper方法可以是在调用子类的方法的同时调用出父类中的相同方法。
注:在输出的时候,会先输出父类中的方法。
import os
omport sys
也可以这样:
from subprocess import Popen, PIPE
1 if foo == 'blah': do_blah_thing()
2 for x in lst: total += x
3 while t < 10: t = delay()