那些被渐渐遗忘的python知识点

Posted 夏小悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了那些被渐渐遗忘的python知识点相关的知识,希望对你有一定的参考价值。

文章目录

前言

  正所谓:时运则存,不用则亡,这些有关python的知识点你还记得多少。

1. 上下文管理器

  无论是书籍还是博客,提到with就和读写文件联系在一起,之所以这么用是因为with相当于对 try...except...finally 模式进行了封装,即使文件读写有错误,也能保证资源的正确释放,渐渐地就认为with要和open()一起用,来读写文件。
  当然啦,with不仅仅用于读写文件,用作者的话说就是,with语句用于包装带有使用上下文管理器定义的方法的代码块的执行。例子如下:

with expr[ as var]:
	code_block 

  上述代码执行的顺序如下:

  1. 对上下文表达式进行求值来获得上下文管理器;
  2. 载入上下文管理器的 __enter__() 以便后续使用;
  3. 载入上下文管理器的 __exit__() 以便后续使用;
  4. 发起调用上下文管理器的 __enter__() 方法;
  5. 如果 with 语句中包含一个目标(as var),来自 __enter__() 的返回值将被赋值给它(var)
  6. 执行代码块;
  7. 发起调用上下文管理器的 __exit__() 方法。
  8. 如果代码块的退出是由异常导致的,则其类型、值和回溯信息将被作为参数传递给 __exit__(),否则的话,将提供三个 None 参数;
  9. 如果代码块的退出是由异常导致的,并且来自 __exit__() 方法的返回值为假,则该异常会被重新引发; 如果返回值为真,则该异常会被抑制,并会继续执行 with 语句之后的语句;
  10. 如果代码块由于异常以外的任何原因退出,则来自 __exit__() 的返回值会被忽略,并会在该类退出正常的发生位置继续执行。
  11. 如果在对目标列表赋值期间发生错误,则会将其视为在语句体内部发生的错误。

  含有__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是绑定在一起的,a1a2都是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知识点的主要内容,如果未能解决你的问题,请参考以下文章

那些被渐渐遗忘的python知识点

那些被渐渐遗忘的python知识点

Python中怕遗忘的知识点总结(持续更新)

闰猹抄

转载App测试中的那些不可遗忘的基础知识

软件測试中的那些不可遗忘的基础知识