目录
一、面向对象基础
1.类的定义
一个类包含属性,方法(函数)
定义方式如下:
class 类名:
类属性
类方法
创建类对象,然后才能通过该对象调用类
创建一个对象的方式:
变量名 = 类名()
调用方式:
变量名.方法()
class Dog:
"""
定义了一个狗类
"""
def eat(self):
print("吃狗粮")
def introduce(self):
print("我的名字是{},我今年{}岁了!".format(dog1.name,dog1.age))
# 创建一个对象
dog1 = Dog()
dog1.eat()
还可以创建多个对象调用该类
给对象添加属性:
变量名.属性 = 属性值(最好不使用这种方式)
# 创建一个对象
dog1 = Dog()
# 给对象添加属性
dog1.name = "史努比"
dog1.age = 4
# 调用对象的方法
dog1.introduce()
# 又创建一个对象
dog2 = Dog()
# 给对象添加属性
dog2.name = "布鲁托"
dog2.age = 2
# 调用对象的方法
dog2.introduce()
print(dog1)
print(dog2)
2.self
self可以理解为指针,哪个对象调用就指向哪个对象
将Dog类中的introduce方法进行修改,用self调用类属性,这样实例对象就可以灵活地改变
class Dog:
"""
定义了一个狗类
"""
def eat(self):
print("{}在吃骨头!".format(self.name))
def introduce(self):
print("我的名字是{},我今年{}岁了!".format(self.name, self.age)
3.__init__方法
该方法一般用于初始化对象基本信息,__init__方法不需要手动调用,在对象初始化的时候自动调用
class Dog():
def __init__(self, new_name, new_age):
"""
__init__方法一般用于初始化对象基本信息
:param new_name: 狗的名字
:param new_age: 狗的年龄
"""
self.name = new_name
self.age = new_age
def introduce(self):
print("我的名字叫{}, 我今年{}岁了!".format(self.name, self.age))
# 创建一个对象
dog1 = Dog("史努比", 8) # 初始化列表
dog1.introduce()
dog2 = Dog("拉布拉多", 3) # 初始化
dog2.introduce()
4.__str__方法
一般用于用户格式化输出对象内容,是一种魔方方法
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "我的名字是{},我今年{}岁了。".format(self.name, self.age)
# 创建对象
dog1 = Dog("史努比", 8)
dog2 = Dog("布鲁托", 3)
print(dog1)
print(dog2)
# 手动删除对象
del dog1
5.__del__方法
当对象消亡(死了)的时候,自动调用这个方法,当我们想要在对象死亡的时候做些什么事情,可以使用这个方法
6.私有属性和方法
私有属性定义方法:在属性前面加两个下划线
注意:在Python中没有绝对的私有,其实当我们去定义私有属性的时候,会对这个属性名字去做处理
会在这个属性的前面加上 _类名
class Woman:
def __init__(self,name,age):
"""
初始化姓名和年龄
"""
self.name = name
# 添加一个私有属性
self.__age = age
def __secret(self):
"""
定义私有方法
"""
print("我叫{},我今年{}岁了!".format(self.name,self.__age))
# 实例化对象
woman1 = Woman("小彤",19)
woman1.__age = 20
# woman1.__secret()
woman1._Woman__secret()
print(woman1.__dict__)
7.使用get和set方法封装私有属性
为了按照条件来进行访问权限的控制,可以通过提供一个公有的方法访问私有属性或者方法。
class Read:
"""
阅读类
"""
# 私有方法
def __reader(self):
print("SVIP会员小说阅读中!")
# 提供用get方法提供一个公有的方法对私有的方法访问
def get_BuyVip(self,money):
if money > 20:
self.__reader()
else:
print("对不起请充值会员")
# 创建对象
qq = Read()
qq.get_BuyVip(10)
二、面向对象的特征
1.继承
需要继承一个类的方法:
类名(要继承的类名)
# 父类
class Animal:
def eat(self):
print("吃")
def drink(self):
print("喝")
def play(self):
print("玩")
# 子类
class Dog(Animal):
def brak(self):
print("汪汪汪")
# 子类
class Cat(Animal):
def brak(self):
print("喵喵喵")
wangcai = Dog()
wangcai.eat()
wangcai.brak()
jiafei = Cat()
jiafei.eat()
jiafei.play()
jiafei.brak()
继承具有传递性:子类可以使用父类,也可以使用父类的父类等
注意:object是所有类的父类
同级之间不能相互借用属性
如果子类重写了父类的方法,方法调用时调用子类的方法,同名情况下,采用就近原则
class Dog(Animal):
def drink(self):
# 这是子类特有的要求
print("这只狗在吃东西!")
# 调用父类的方法,可以使用super
super().drink()
# 也可以直接使用父类的名称.方法
Animal.drink(self)
# 不要子类调用自己的方法,会递归进入死循环
# Dog.drink(self)
# 如果子类重写了父类的方法,方法调用时调用子类的方法,同名情况下,采用就近原则
dog1 = Dog()
dog1.drink()
子类不能访问父类的私有属性和方法
class A:
def __init__(self):
"""
初始化信息
"""
self.name = "老王"
self.__age = 18
def __eat(self):
"""
私有方法
"""
print("私有方法eat{}{}".format(self.name, self.__age))
def eat(self):
"""
公有方法
"""
print("公有方法eat{}{}".format(self.name, self.__age))
class B(A):
pass
"""
def test(self):
# 1.子类不能访问父类的私有方法
print(self.__age)
print(super().__age)
# 2.子类不访问父类的私有方法
self.__eat()
# 3.子类可以访问父类的公有方法
super(B, self).eat()
# 4.子类访问父类的公有属性
print("父类的共有属性:{}".format(self.name))
"""
b = B()
# 在外界可以直接访问父类的共有属性,或调用父类的公有方法
print(b.name)
b.eat()
多继承:
可以让子类继承多个父类的方法和属性
多继承需要注意对象调用的顺序
__mro__方法可以用来查询对象调用的顺序
class A:
def test(self):
print("---A---")
class B:
def test(self):
print("---b---")
class C(B, A):
def test1(self):
print("---c---")
c = C()
c.test() # 打印结果:---b---
# 使用方法查询C类对象的调用顺序
print(C.__mro__)
# 结果:(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
2.多态
python是弱数据类型语言,所以多态不是太明显
多态的含义:定义的时候不确定调用哪个类里面的方法,而是执行的时候才确定
class Animal:
def introduce(self):
print("我是一只神奇的动物,感谢各位的关照!")
class Dog(Animal):
def introduce(self):
print("飞天旺财在此,感谢各位的关照!")
class Cat(Animal):
def introduce(self):
print("我是一只加菲猫!")
def introduce(temp):
temp.introduce()
a = Animal()
b = Dog()
c = Cat()
introduce(a)
introduce(b)
introduce(c)
3.__new__方法
__new__方法是一个类在实例化的时候会被自动调用的,没有写会默认调用父类的__new__方法。
这个方法其实就是为了完成对象的创建,所以如果说需要重写__new__方法的时候,一定要调用一下父类的__new__
class Test:
def __init__(self):
print("init")
def __str__(self):
print("str")
def __del__(self):
print("del")
def __new__(cls, *args, **kwargs): # 实际上就是为类开辟空间的
# cls 指向类对象 new 会先被调用
print("new")
return super().__new__(cls)
t = Test()
"""
结果:
new
init
del
"""
4.单例
在某种情况下,我们多次创建实例希望指向的是同一个对象, 比如回收站,每次用的时候不要创建多个,一个就行 创建多个实例对象指向的是同一个内存地址
class Box:
# 定义类属性保存引用
__instance = None
# 定义类属性保存init方法是否执行
__init_flag = False
def __new__(cls, *args, **kwargs):
"""
对象初始化时自动调用
"""
if cls.__instance is None:
# 调用父类__new__方法创建空间,获取内存地址,保存在类属性
cls.__instance = object.__new__(cls)
return cls.__instance
else:
return cls.__instance
def __init__(self, name):
if Box.__init_flag:
pass
else:
self.name = name
Box.__init_flag = True
5.捕获异常
try:
num = int(input("请输入一个数字:"))
# print(num/0)
# open("xx.txt", "r")
except (ZeroDivisionError, ValueError):
print("如果出现ZeroDivisionError, ValueError就执行这里的代码")
except Exception as ret:
print("未知错误{}".format(ret))
else:
print("如果else和try,except联合使用,没有异常的情况下才会执行!")
finally:
print("finally不管你有没有异常,都会执行")