python 面向对象(二)类的继承-多态-经典类和新式类-静态方法,类方法,实例方法-python中的下划线-常用魔术方法
目录
1. 类的继承
1.1 面向对象的好处

############################################
1.2 示例
class Animal():
species = "animal"
count = 0
def __init__(self):
self.name = "animal"
Animal.count += 1
print("初始化animal...")
def breath(self):
print("i can breath")
def eat(self):
print("i can eat")
class Person(Animal):
# 重写父类的属性 species
species = "Person"
animal1 = Animal()
print(animal1.count)
# 初始化自己没有init,会执行父类的__init__
p = Person()
print(p.species, p.count)
print(p.name)
class Dog(Animal):
def __init__(self):
print("i am dog")
# 重写父类eat方法
def eat(self):
print("dog is eating...")
d = Dog()
# # person类没有init,会调用父类init
# # 父类init有name属性,所以不会报错
# print(p.name)
# # dog类自己有init,不会再调用父类init
# # dog类init里面没有name属性,会报错
# print(d.name)
d.eat()
############################################
1.3 super()方法
如果一个子类的__init__方法想使用父类的__init__中的属性,这个时候可以使用super()方法
但是super()方法一般写在最前面,因为如果写在后面的话父类的__init__方法可能会覆盖子类的
一些属性。
class Pig(Animal):
count = 0 # 重写父类属性
def __init__(self):
# 调用父类的init
super().__init__()
# super().eat()
self.name = "pig"
Pig.count += 1
print("初始化pig")
print('*' * 20)
pig1 = Pig()
print(pig1.count, animal1.count)
********************
初始化animal...
初始化pig
1 3
############################################
1.4 类和实例的关系
1.4.1 isinstance ()函数
isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。
isinstance() 与 type() 区别:
type() 不会认为子类是一种父类类型,不考虑继承关系。
isinstance() 会认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()。
语法
以下是 isinstance() 方法的语法:
isinstance(object, classinfo)
############################################
1.4.2 示例:判断类与实例的关系
# 类与实例的关系
print('*'*20)
print(isinstance(pig1, Pig), isinstance(pig1, Animal))
print(type(pig1))
a = str(10)
# 所谓的工厂函数其实本质就是类
# ’ABC‘.lower(),就是类调用lower方法
print(type(a), str.lower("ABC"), "ABC".lower())
********************
True True
<class '__main__.Pig'>
<class 'str'> abc abc
############################################
2.多态
2.1 Python中的多态
class zhifubao():
def pay(self):
print("this is zhifubao pay")
class weixin():
def pay(self):
print("this is weixin pay")
class bank():
def pay(self):
print("this is bank pay")
z = zhifubao()
w = weixin()
b = bank()
def pay(obj): # 接口的多种形态,接口的重用
obj.pay()
pay(z)
pay(w)
pay(b)
E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/05.多态.py
this is zhifubao pay
this is weixin pay
this is bank pay
Process finished with exit code 0
############################################
2.2 Python中的多态- 注意
2.3 多态性的好处
3. 经典类和新式类
3.1. python2和python3的类型区别
python3里面默认所有类都是继承的object,所以python3都是新式类
# 经典类 通过type查看到的实例都是 instance
# 类和实例只能通过.__class__属性
# 新式类 通过type查看到的实例类型就是类名
<class '__main__.A'>
# __main__代表当前模块
# 代表当前模块下的A类
[root@localhost lianxi]# python2
Python 2.7.5 (default, Oct 14 2020, 14:45:30)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class A: pass
...
>>> a = A()
>>> type(a)
<type 'instance'>
>>> a.__class__
<class __main__.A at 0x7f2a02719258>
>>>
─────────────────────────────────────────────────────────────────
[root@localhost ~]# python3
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class A: pass
...
>>> a = A()
>>> type(a)
<class '__main__.A'>
>>> a.__class__
<class '__main__.A'>
>>>
############################################
3.2 类的多重继承
3.2.1 类可以多重继承

class A():
def test(self):
print("from A")
class B(A):
def test(self):
print("from B")
class C(A):
def test(self):
print("from C")
class D(B):
def test(self):
print("from D")
class E(C):
def test(self):
print("from E")
class F(D, E):
def test(self):
print("from F")
f = F()
f.test()
经典类: F--D--B--A--E--C
新式类: F--D--B--E--C--A
############################################
3.2.2 经典类和新式类的继承顺序

############################################
3.2.3 经典类与新式类的继承继承原理
3.2.4 C3算法
# c3算法 # 首先将自身类加入本序列,然后再对继承序列的元素依次判断 # 若某个元素不在其他序列或者他是所有继承序列的第一个,那么就把这个元素提取到本序列
############################################
4. 静态方法,类方法,实例方法
class A:
name = "class A"
def __init__(self): # 自动调用
self.country = "china"
# 实例方法,第一参数代表实例本身
def normal_method(self, name):
# 方法的里面,即可以访问类属性,又可以访问实例属性
print("normal:")
print(self.name, name)
# 类方法 cls代表类
@classmethod # 装饰器 被装饰器装饰过的方法称为类方法
def class_method(cls, name):
# 类方法可以类属性
print("classmethod")
print(cls, cls.name)
@staticmethod # 静态方法
def static_method(name):
# 静态方法可以通过类名去访问类属性
print("static_method", name, A.name)
a1 = A()
# 静态方法,实例方法,类方法都能通过实例去调用
a1.normal_method("a1")
a1.class_method("a1")
a1.static_method("a1")
# 也可以通过类去调用
# 类调用实例方法需要传入实例参数
A.normal_method(a1, "A")
A.class_method("A")
A.static_method("A")
############################################
4.1 实例方法
实例方法,第一参数代表实例本身
在实例方法里面即可以访问类属性,又可以访问实例属性
# 实例方法,第一参数代表实例本身
def normal_method(self, name):
# 方法的里面,即可以访问类属性,又可以访问实例属性
print("normal:")
print(self.name, name)
############################################
4.2 类方法 @classmethod
@classmethod --> 装饰器
被装饰器装饰过的方法称为类方法
类方法可以访问类属性
# 类方法 cls代表类
@classmethod # 装饰器 被装饰器装饰过的方法称为类方法
def class_method(cls, name):
# 类方法可以类属性
print("classmethod")
print(cls, cls.name)
############################################
4.3 静态方法 @staticmethod
静态方法可以通过类名去访问类属性
@staticmethod # 静态方法
def static_method(name):
# 静态方法可以通过类名去访问类属性
print("static_method", name, A.name)
############################################
4.4 各种方法的区别
############################################
5. python中的下划线
############################################
5.1 以单下划线开头的
5.1.1 在类里面
5.1.2 在模块里面
############################################
5.2 以双下划线开头的
5.2.1 在类里面
5.2.2 在模块里面
不能模糊导入模块 即 不能用“ from xxx import *“导入包/模块。
class P:
"""
this is P
"""
_min = 1 # 保护属性
__max = 10 # 私有属性
def __init__(self):
self.name = "sc"
self.age = 4
self.__desc = "it"
def __make(self):
print("这是一个私有方法")
print(self.__desc)
def _protectmake(self):
print("这是一个保护方法")
def show(self):
print(self.__max, self.__desc)
class Child(P):
def show(self):
print(self.__max)
#
#
p = P()
c = Child()
# 保护属性和普通属性没有区别
print(c._min, p._min, Child._min, P._min)
# 访问私有属性 子类访问不到私有成员
# print(c.__make)
# 类对象也不能访问私有成员
# print(p.__max)
# p.__make()
# 想访问__make()要加上类名 p._P__make()
# 私有成员只能在类的内部访问
p.show()
print('*' * 20)
print(c._min)
# print(dir(p))
# '_P__desc', '_P__make', '_P__max',
# python中的私有都是伪私有,实际其实就是将双下划线开头的标识符
# 改了一个名字存储 _类名__标识符
E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/08.python中的下划线.py
1 1 1 1
10 it
********************
1
Process finished with exit code 0
############################################
5.3 以双下划线开头和双下划线结尾的
# 常见的以双下划线开头和以双下划线结尾的特殊变量
# __dict__ # 查看命名空间
print(P.__dict__)
print(p.__dict__)
print(P.__name__)
# __class__ 查看对象属于哪个类
print(p.__class__)
# __module__ 查看所在哪个模块
print(P.__module__)
#
# __doc__文档注释, 类,函数的文档注释都会放到 __doc__里面
print(P.__doc__)
E:\python\python3.9.1\python.exe E:/tlbb/2022-05-28-python面向对象/08.python中的下划线.py
{'__module__': '__main__', '__doc__': '\n this is P\n ', '_min': 1, '_P__max': 10, '__init__': <function P.__init__ at 0x0000021A1689DC10>, '_P__make': <function P.__make at 0x0000021A168E1940>, '_protectmake': <function P._protectmake at 0x0000021A168E19D0>, 'show': <function P.show at 0x0000021A168E1A60>, '__dict__': <attribute '__dict__' of 'P' objects>, '__weakref__': <attribute '__weakref__' of 'P' objects>}
{'name': 'sc', 'age': 4, '_P__desc': 'it'}
P
<class '__main__.P'>
__main__
this is P
Process finished with exit code 0
############################################
6.python中常见的魔术方法
魔术方法 :一般以双下划线开头和双下划线结尾
而且是有特殊含义的方法,一般不需要手动去调用
它会在某种特定场景下自动执行
构造函数(__new__/__init__)
析构函数(__del__)
class A:
def __del__(self):
print("this is A.del")
a1 = A()
del a1
print("xxxxxx")
调用方法(__call__)
class A:
def __call__(self, name):
print(f"i am A.__call__,name is {name}")
a1 = A()
a1("sc")
def func1():
pass
print(dir(func1))
自定义异常类
class NotIsIntException(Exception):
def __str__(self):
return 'NotIsIntException类型不是整数'
n = input('请输入一个整数')
try:
if n.isdigit():
print(n)
else:
raise NotIsIntException
except NotIsIntException as ni:
print(ni)
############################################
获取数据(__getitem__)
删除数据(__delitem__)
设置数据(__setitem__)
class A:
def __init__(self):
self.data = {}
def __getitem__(self, key):
print("get data")
return self.data.get(key, 0)
def __setitem__(self, key, value):
print("set data:", key, value)
self.data[key] = value
def __delitem__(self, key):
print("delete data")
del(self.data[key])
a1 = A()
print(a1["key1"])
a1["key1"] = "xxxxxxx"
del a1["key1"]
############################################
其他魔术方法
class B:
def __init__(self, num):
self.num = num
def __add__(self, x):
print("this is add")
return self.num + x
a = B(4)
print(a + 6)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通