每日5个Python小技巧-day1
1. 断言assert
(1)用法
assert expression, 'message'
? 当expression语句不满足的时候会raise一个AssertionError(报错),能确保assert语句以后的代码都满足expression。
(2)应用
? 告诉程序员发生不可恢复的错误,用于程序的内部自检,说明程序中不可能出现的情况。用于简单的自定义异常错误警告。
(3)注意
? · 不能用于检验数据
? 在命令行中使用-o 和-oo 标识能全局禁用断言。
(4)例子
def AssertTest(num_):
assert num_ > 10, 'num is less than 10'
print(num_)
if __name__ == '__main__':
num = int(input("输入num: "))
AssertTest(num)
? 当输入3时,程序报错:
AssertionError: num is less than 10
2.上下文管理:在自定义类中支持with语句
(1)给自定义的对象添加__enter 和__exit__ 方法。当执行流程进入with语句上下文时,Python会调用__enter 获取资源;离开with上下文时,Python会调用__exit__ 释放资源.
(2)例子
class withClass:
def __init__(self):
self.resource = 0
def __enter__(self):
self.resource += 1
print(f'获取资源resource: {self.resource}')
def __exit__(self, exc_type, exc_val, exc_tb):
self.resource = 0
print(f"释放资源resource: {self.resource}")
if __name__ == '__main__':
with withClass() as test:
pass
输出:
获取资源resource: 1
释放资源resource: 0
(3)应用
? 文件的读写;数据的清洗或预处理;资源的自动获取与释放相关,避免资源的占用(如数据文件和数据库的连接等)。
3.上下文管理:@contextlib.contextmanager
(1)使用@contextlib.contextmanager 装饰器能够为资源定义一个基于生成器的工厂函数,该函数将自动支持with语句。
(2)引用一个例子
@contextmanager
def book_mark():
print('《', end='')
yield
print('》', end='')
if __name__ == '__main__':
with book_mark():
print("且将生活一饮而尽", end='')
[out] 《且将生活一饮而尽》
(3)例子2-一个简单的计时器
@contextmanager
def timeit():
start = time.time()
yield
end = time.time()
print(f"耗时:{end-start}s")
def func():
time.sleep(3)
if __name__ == '__main__':
with timeit() as test:
func()
耗时:3.0065133571624756s
? 上下文管理器可充当于装饰器类似的作用,可以在不改变原函数的基础上增加一些方法,增强了封装性和复用性.
4. 单下划线
(1)前置单下划线
? 对程序本身没有影响,只是一种提示----Python社区约定好单下划线的变量或者方法只能在类的内部使用。
(2)后置单下划线
? 用于避免变量的命名与Python内置关键字冲突,例如bs4中用于查找<div class="container">...</div> 的标签,使用的参数class_='container' ;以及命名会与内置关键字冲突。
? 我通常会用单下划线标识函数中会与主函数相同的变量名。
5.双下划线
(1)前置下划线
? 前置双下划线会让Python解释器重写属性名称,避免子类中的命名冲突。这也成为名称改写,即解释器会更改变量的名称。
? a. 例子
_MyClass__myname = "myClass"
class MyClass:
def getMyname(self):
print(__myname)
if __name__ == '__main__':
MyClass().getMyname()
[out] myClass
? 这个例子表明_MyClass__myname = "myClass" 为全局变量,然后再MyClass 的类环境中访问变量。由于名称改写,类中getMyname() 方法仅用__myname 就能引用_MyClass__myname 全局变量。
b. 双下划线也能为类表明私有属性
class MyClass:
def __init__(self):
self.__data = 1234
if __name__ == '__main__':
mc = MyClass()
print(mc.__data)
[out] AttributeError: 'MyClass' object has no attribute '__data'
? 然而用这个方法表明私有属性也存在风险,通过下面的方法也可以访问到data
mc = MyClass()
print(mc._MyClass__data)
[out] 1234
c.前后双下划线
? 某些前后双下划线名的方法在类中是表示一些特殊的方法,后续会慢慢揭晓。需要注意的是自定义变量名或函数名时,尽量避免使用前后双下划线的命名。
|