No.21特殊成员&异常处理
No.21
今日概要
- 嵌套
- 特殊成员:
__init__ - type / isinstance / issubclass / super
- 异常处理
内容回顾
def login():
pass
login()
class Account:
def login(self):
pass
obj = Account()
obj.login()
-
谈谈你了解的面向对象?
- 封装
- 继承
- 多态
-
类和对象是什么关系?
-
对象是类的一个实例
class Foo: def __init__(self, name): self.name = name def run(self) pass obj1 = Foo('alex') obj2 = Foo('eric')
-
-
self 是什么?
-
本质就是一个形式参数
# self就是一个形式参数,对象调用方法是,Python内部会将对象传给这个参数。 class Foo: def run(self, num): # num形参需要自己传实参 pass obj = Foo() obj.run(5)
-
-
类成员 & 对象成员 以及它们之间的关系
class Foo: name = 'alex' def run(self): pass obj = Foo() -
类 / 对象 / 方法 都可以当作变量或嵌套到其它类型中。
class Foo: def run(self): pass v = [Foo, Foo] v = [Foo(), Foo()] obj = Foo() v = [obj.run, obj.run]class School(object): def __init__(self, title): self.title = title class Course(object): def __init__(self, name, school_obj) self.name = name self.school_obj = school_obj class Classes(object): def __init__(self, cname, course_obj) self.cname = cname self.course_obj = course_obj s1 = School('北京') c1 = Course('Python', s1) c2 = COurse('Go', s1) cl1 = Classes('全栈1期', c1)# 方法在定义的时候,一般情况下是对类的对象做操作或做处理的。 class School(object): def __init__(self, title): self.title = title def rename(self): # 学校改名 pass class Course(object): def __init__(self, name, school_obj) self.name = name self.school_obj = school_obj def reset_price(self): # 课程改价 pass class Classes(object): def __init__(self, cname, course_obj) self.cname = cname self.course_obj = course_obj def shangke(self): # 班级上课 pass s1 = School('北京') c1 = Course('Python', s1) c2 = COurse('Go', s1) cl1 = Classes('全栈1期', c1)
内容详细
1.嵌套
- 函数:参数可以是任意类型。
- 字典:类和对象都可以做字典的key和value
- 继承的查找关系
class StarkConfig(object):
pass
class AdminSite(object):
def __init__(self):
self.data_list = []
def register(self, arg):
self.data_list.append(arg)
site = AdminSite()
obj = StarkConfig()
site.register(obj)
class StarkConfig(object):
def __init__(self, name, age):
self.name = name
self.age = age
class AdminSite(object):
def __init__(self):
self.data_list = []
self.sk = None
def set_sk(self, arg):
self.sk = arg
site = AdminSite() # data_list = [] sk = None
site.set_sk(StarkConfig) # sk = StarkConfig
site.sk('alex', 18)
class StarkConfig(object):
pass
class Foo(object):
pass
class Base(object):
pass
class AdminSite(object):
def __init__(self):
self._register = {}
def registry(self, key, arg):
self._register[key] = arg
site = AdminSite()
site.registry(1, StarkConfig)
site.registry(2, StarkConfig)
site.registry(3, StarkConfig)
site.registry(4, Foo)
site.registry(5, Base)
for k, v in site._register.items():
print(k, v())
class StackConfig(object):
pass
class UserConfig(StackConfig):
pass
class AdminSite(object):
def __init__(self):
self._register = {}
def registry(self, key, arg=StackConfig):
self._register[key] = arg
def run(self):
for key, value in self._register.items():
obj = value()
print(key, obj)
site = AdminSite()
site.registry(1)
site.registry(2, StackConfig)
site.registry(3, UserConfig)
site.run()
class StackConfig(object):
list_display = '666'
class UserConfig(StackConfig):
list_display = '888'
class AdminSite(object):
def __init__(self):
self._register = {}
def registry(self, key, arg=StackConfig):
self._register[key] = arg
def run(self):
for key, value in self._register.items():
obj = value()
print(key, obj.list_display)
site = AdminSite()
site.registry(1)
site.registry(2, StackConfig)
site.registry(3, UserConfig)
site.run()
class StackConfig(object):
list_display = '666'
def changelist_view(self):
print(self.list_display)
class UserConfig(StackConfig):
list_display = '888'
class AdminSite(object):
def __init__(self):
self._register = {}
def registry(self, key, arg=StackConfig):
self._register[key] = arg
def run(self):
for key, value in self._register.items():
obj = value()
obj.changelist_view()
site = AdminSite()
site.registry(1)
site.registry(2, StackConfig)
site.registry(3, UserConfig)
site.run()
2.特殊成员
2.1__init__
class Foo:
'''
对类注释
'''
def __init__(self, a1):
'''
初始化方法
'''
self.a1 = a1
obj = Foo('alex')
2.2__new__
# Python中当类实例化对象时,会先执行类中的new方法,再执行init方法。
# Python会使我们创建类默认继承object类,所以我们在创建的类中即使不写new方法,当实例化对象时我们创建的类会调用object类中的new方法来创建空的对象,在执行我们创建类中的init方法给空的对象中赋值。
class Foo(object):
def __init__(self, a1):
'''
用于给对象中赋值(初始化方法)
'''
print('给对象中进行赋值')
self.a1 = a1
def __new__(cls, *args, **kwargs):
'''
用于创建空的对象(构造方法)
'''
print('创建对象')
return object.__new__(cls) # return返回什什么对象就是什么
obj = Foo()
# 默认new方法返回的是一个空的内存地址给对象,所以init方法才能在空地址中赋值。如果我们在类中让new返回123,那么创建的对象就是123,init方法就没有办法给对象赋值(此时对象不是一个空的内存地址)。
2.3__call__
# 对象后面加括号会执行call方法
class Foo:
def __call__(self, *args, **kwargs):
print('执行call方法')
obj = Foo()
obj()
Foo()()
2.4get / set / del
__getitem__ __setitem__ __delitem__
class Foo(object):
def __setitem__(self, key, value):
print(key,value)
def __getitem__(self, item):
return item+'加油'
def __delitem__(self, key):
pass
obj1 = Foo()
obj1[666] = 888 # 此语法会让对象自动调用类中__setitem__方法
val = obj1['中国'] # 此语法会让对象自动调用类中__getitem__方法
print(val)
del obj1['alex'] # 此语法会让对象自动调用类中__delitem__方法
2.5__str__
class Foo(object):
def __str__(self):
'''
只有在打印对象时,会自动调用此方法,并将返回值在页面显示出来。
'''
return 11
obj = Foo()
print(obj, type(obj))
class User(object):
def __init__(self, name, email):
self.name = name
self.email = email
def __str__(self):
return '%s %s'%(self.name, self.email)
user_list = [User('张三', '123@qq.com'), User('李四', '456@qq.com')]
for item in user_list:
# print(item.name, item.email)
print(item)
2.6__dict__
class Foo(object):
def __init__(self, name, age):
self.name = name
self.age = age
obj = Foo('alex', '18')
print(obj)
print(obj.name)
print(obj.age)
val = obj.__dict__ # 去对象中找到所有变量,并将其转换为字典
print(val)
2.7上下文管理 (面试题)
class Foo(object):
def __enter__(self):
self.a = open('test.txt', 'a', encoding='utf-8')
return self.a # 返回什么as后面的变量就是什么
def __exit__(self, exc_type, exc_val, exc_tb):
self.a.close()
# 此语法会执行对象中的enter方法,然后返回值给as后面的变量
with Foo() as f:
f.write('alex')
f.write('alex')
f.write('alex')
# 面试题:添加代码使下面代码能实现。
'''
class Context:
pass
with Context() as ctx:
ctx.do_something()
'''
class Context:
def __enter__(self):
print('进入')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('退出')
def do_something(self):
print('内部执行')
with Context() as ctx:
ctx.do_something()
2.8对象相加 (面试题)
#加减乘除都有对应的方法
class Foo(object):
def __add__(self, other):
return 123 # 返回什么val就是什么
obj1 = Foo()
obj2 = Foo()
val = obj1 + obj2 # 会调用add方法,obj1传给self,obj2传给other
特殊成员:就是为了能够快速实现执行某些方法而生。
3.内置函数补充
3.1 type()
# 查看类型
class Foo():
pass
obj = Foo()
if type(obj) == Foo:
print('obj是Foo的对象')
3.2 issubclass()
# 判断第一个类是不是第二个类的继承类(会考虑多继承)
class Base:
pass
class Show(Base):
pass
class Foo(Show):
pass
class Bar:
pass
print(issubclass(Bar, Base)) # False
print(issubclass(Foo, Base)) # True 虽然Foo不是Base的直接继承类但是是Base多继承类。
3.3 isinstance()
# 判断对象是否是某个类的或其继承类的实例
class Base(object):
pass
class Foo(object):
pass
class Bar(Base):
pass
obj = Bar()
print(isinstance(obj, Foo)) # False
print(isinstance(obj, Bar)) # True
print(isinstance(obj, Base)) # True
'''
type() 不考虑继承关系。
isinstance() 考虑继承关系。
'''
4.super函数
class Base(object):
def func(self):
print('base.func')
return 666
class Foo(Base):
def func(self):
result = super().func()
print('foo.func')
print(result)
obj = Foo()
obj.func()
# super().func() 根据self对象所属类的继承关系,按继承顺序往下继续找同名方法并执行。(只要找到一个就不再找了)
class Bar(object):
def func(self):
print('bar.func')
return 888
class Base(Bar):
pass
class Foo(Base):
def func(self):
result = super().func()
print('foo.func')
print(result)
obj = Foo()
obj.func()
# super().func() 根据self对象所属类的继承关系,按继承顺序往下继续找同名方法并执行。(只要找到一个就不再找了)
class Base(object):
def func(self):
super().func()
print('foo.func')
class Bar(object):
def func(self):
print('bar.func')
class Foo(Base,Bar): # Foo → Base → Bar
pass
obj1 = Foo()
obj1.func()
obj2 = Base()
obj2.func() # 报错
# super().func() 根据self对象所属类的继承关系,按继承顺序往下继续找同名方法并执行。(只要找到一个就不再找了)
5.异常处理
5.1基本格式
try:
pass
except Exception as e:
pass
# 全部捕获
try:
# int('alex')
v = []
v[100]
except Exception as e:
print(e) # e是Exception类的对象,对象中有一个错误信息。
'''
int('alex') # ValueError
v = []
v[100] # IndexError
'''
# 可以捕获
try:
int('alex')
except ValueError as e:
print(e)
# 捕获不到
try:
v = []
v[100]
except ValueError as e:
print(e)
try:
v = []
v[100]
except ValueError as e:
print(e)
except IndexError as e:
print(e)
except Exception as e:
print(e)
try:
v = []
v[100]
except ValueError as e:
print(e)
except IndexError as e:
print(e)
except Exception as e:
print(e)
finally: # 无论对错都会执行
print('最后')
def func():
try:
v = 1
return 123
except Exception as e:
print(e)
finally: # 特殊:即使放在函数,遇到return也会执行。
print('最后')
func()
5.2主动触发异常
try:
int('666')
raise Exception(888) # 代码中主动抛出异常
except Exception as e:
print(e) # 结果888
# 写一个函数,判断alex是否在文件中。
def func():
result = True
try:
with open('test.txt','r',encoding='utf-8') as f:
data = f.read()
if 'alex' not in data:
raise Exception()
except Exception as e:
result = False
return result
5.3自定义异常
class MyException(Exception):
def __init__(self, message):
super().__init__()
self.message = message
try:
raise MyException('alex')
except MyException as e:
print(e.message)
总结
- 特殊成员 ▲
- 嵌套
- type / issubclass / isinstance()
- super
- 异常

浙公网安备 33010602011771号