那些被渐渐遗忘的python知识点
Posted 夏小悠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了那些被渐渐遗忘的python知识点相关的知识,希望对你有一定的参考价值。
文章目录
前言
正所谓:时运则存,不用则亡,这些有关python的知识点你还记得多少。
1. 上下文管理器
无论是书籍还是博客,提到with
就和读写文件联系在一起,之所以这么用是因为with
相当于对 try...except...finally
模式进行了封装,即使文件读写有错误,也能保证资源的正确释放,渐渐地就认为with
要和open()
一起用,来读写文件。
当然啦,with
不仅仅用于读写文件,用作者的话说就是,with
语句用于包装带有使用上下文管理器定义的方法的代码块的执行。例子如下:
with expr[ as var]:
code_block
上述代码执行的顺序如下:
- 对上下文表达式进行求值来获得上下文管理器;
- 载入上下文管理器的
__enter__()
以便后续使用; - 载入上下文管理器的
__exit__()
以便后续使用; - 发起调用上下文管理器的
__enter__()
方法; - 如果
with
语句中包含一个目标(as var)
,来自__enter__()
的返回值将被赋值给它(var)
; - 执行代码块;
- 发起调用上下文管理器的
__exit__()
方法。 - 如果代码块的退出是由异常导致的,则其类型、值和回溯信息将被作为参数传递给
__exit__()
,否则的话,将提供三个None
参数; - 如果代码块的退出是由异常导致的,并且来自
__exit__()
方法的返回值为假,则该异常会被重新引发; 如果返回值为真,则该异常会被抑制,并会继续执行with
语句之后的语句; - 如果代码块由于异常以外的任何原因退出,则来自
__exit__()
的返回值会被忽略,并会在该类退出正常的发生位置继续执行。 - 如果在对目标列表赋值期间发生错误,则会将其视为在语句体内部发生的错误。
含有
__enter__()
和__exit__()
方法的对象称为上下文管理器。
class AClass(object):
def __init__(self):
self.count = 0
def __enter__(self):
print('先执行__enter__')
self.count = 1
return self
def __exit__(self, exc_type, exc_value, traceback):
print('退出时执行__exit__')
def afunc():
return AClass()
if __name__ == '__main__':
with AClass() as f:
print(f.count)
print('这是code block')
# with afunc():
# print('这是code block')
# 先执行__enter__
# 1
# 这是code block
# 退出时执行__exit__
含有多个上下文管理器时可以这样使用with
:
# method 1
with A() as a, B() as b:
code_block
# method 2
with A() as a:
with B() as b:
code_block
# method 3
with (
A() as a,
B() as b,
):
code_block
2. 类属性与实例属性
对于类对象,主要是加深一下对类属性与实例属性的认识,可以这样定义:
类属性:定义在__init__()
之外的属性;
实例属性:定义在__init__()
之内的属性,self.xxx=zzz
;
虽然都是在类里面定义的,但也有些不同的用处,举个简单的栗子:
class A(object):
count = 0
def __init__(self):
A.count += 1
if __name__ == '__main__':
a1 = A()
a2 = A()
print(a1.count)
print(a2.count)
# 2
# 2
这里的count
属性是类属性,即它和A
是绑定在一起的,a1
和a2
都是A
的实例,它们俩共享count
属性。
class A(object):
count = 0
def __init__(self):
self.count += 1
if __name__ == '__main__':
a1 = A()
a2 = A()
print(a1.count)
print(a2.count)
# 1
# 1
如果类属性和实例属性名称一样,从外部访问时,会得到实例属性而不是类属性,很好理解,类已经被实例化了。
对于类变量,还可以这样使用,即调用类变量之前不需要实例化:
class A(object):
count = 0
def __init__(self):
A.count += 1
if __name__ == '__main__':
tmp_ = A()
c = A.count
print('current count is: ', c)
# current count is: 1
3. __call__方法
__call__
方法使得类实例对象可以像调用普通函数那样进行调用,类似于C++在类中对 ()
运算符的重载:
class A(object):
def __init__(self):
pass
def afunc(self):
print('hi~')
def __call__(self, *args, **kwargs):
print('hi~, __call__')
if __name__ == '__main__':
a = A()
a.afunc()
a() # 会调用__call__方法
# hi~
# hi~, __call__
以上是关于那些被渐渐遗忘的python知识点的主要内容,如果未能解决你的问题,请参考以下文章