python技巧 黑魔法指南笔记

本文介绍了一系列Python编程中的高级技巧和不常见的用法,包括逻辑运算符的特殊行为、列表操作的差异、装饰器的设计与应用、上下文管理器的自定义实现、函数重试机制、以及如何利用Python内置特性提高代码效率。
摘要由CSDN通过智能技术生成

python 黑魔法

1.6

False == False == True
False == False and False == True

pass --> …

1.7

or 都为真,返回第一个值
and 都为真,返回第二个值

1.8

sum((a,b,c), [])多表连接

1.9

python3.6 后字典有序,并且字典效率提升

1.11

python中小整数池,[-5,256]

a = 257;b =257 同行赋值区别

1.12

字符串驻留

1.13

from distutils.sysconfig import get_python_lib
print(get_python_lib())

1.15

#!/usr/bin/env python
#!/usr/bin/python

当这个文件有可执行权限,可以./直接执行

1.16

{} ,dict(),第二种调用有函数进出栈,会慢一些

1.19

finally 和 return 之间
finally下有return 优先执行,并且使得try中的return无效,
finally下无return try中的return生效

1.20

字符串之间的缝隙”“

1.27

# =+
>>> a = [1, 2, 3, 4]
>>> b = a
>>> a = a + [5, 6, 7, 8]
>>> a
[1, 2, 3, 4, 5, 6, 7, 8]
>>> b
[1, 2, 3, 4]
# += 
>>> a = [1, 2, 3, 4]
>>> b = a
>>> a += [5, 6, 7, 8]
>>> a
[1, 2, 3, 4, 5, 6, 7, 8]
>>> b
[1, 2, 3, 4, 5, 6, 7, 8]

+= 就地改变,相当于extend;a+[]相当于返回新表

1.30

continue 和break 在遇到上下文管理器优先执行object.__enter__()object.__exit__() ,保证资源释放

2.2查看python包路径

python3 -m site
print(sys.path)

2.3json美化查看

python -m json.tool demo.json

2.6快速FTP服务器

目前测试在linux下可用

python -m SimpleHTTPServer 8888
python3 -m http.server 8888

2.7python文档离线网页

python -m pydoc -p 5200

2.8

多版本Python pip下载包的时候,使用python+版本号 -m 来指定到不同的包目录下

$ python -m pip install requests
$ python3 -m pip install requests
$ python3.8 -m pip install requests
$ python3.9 -m pip install requests

5

多层级列表推导式

>>> list02 = [4,5,6]
>>> list03 = [7,8,9]
>>>
>>> [x for l in (list01, list02, list03) for x in l]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

6heapq

堆排序,对list01、list02和list03中的元素同时排序

>>> from heapq import merge
>>> list(merge(list01, list02, list03))

3.2

字典合并

profile ={"name":"lzf","age":27}
ext_info = {"gender":"male"}

full_dict = {**profile,**ext_info}


{k:v for d in [profile, ext_info] for k,v in d.items()}

3.9后
profile | ext_info   new_dict
ext_info |= profile  就地修改

6exec

>>> with open("/usr/lib64/python2.7/os.py", "r") as f:
... exec(f.read())
...
>>> getcwd()
'/home/wangbm

执行其他文件代码

3.4

<on_true> if <condition> else <on_false>
<condition> and <on_true> or <on_false>

3.6海象

3.8版本后才有海象

if (age:= 20) > 18:
 print("成年了")
文件读取
file = open("demo.txt", "r")
while (line := file.readline()):
 print(line.strip())
密码校验
while (p := input("Enter the password: ")) != "youpassword":
 continue

4.1装饰器

logging 模块原型

class Logger():
	def __init__(self,func):
		self.func = func

	def __call__(self,*args,**kwargs):
		print(f"[Info]: function {self.func.__name__} is running...")
		
		return self.func(*args,**kwargs)

设计一个单例
Python中的单例模式的几种实现方式的及优化 - 听风。 - 博客园 (cnblogs.com)

"""
python 单例模式

"""

instances = {}


def singleton(cls):
    def get_instance(*args, **kwargs):
        cls_name = cls.__name__
        if cls_name not in instances:
            instances[cls_name] = cls(*args, **kwargs)
        return instances[cls_name]

    return get_instance


@singleton
class User:
    def __init__(self, name):
        self.name = name


if __name__ == '__main__':
    u1 = User("lll")
    u1.age = 2
    print(u1.age)

设计类时
使用__slots__进行类属性限制,使用装饰器@property进行修改类属性限制
防止用户为类添加其他属性,或者将某个属性设置成非预期的值

4.2访问描述符

数据描述符 实现了__ get __ 和__ set __ 两种
非数据描述符 只实现__ get __

相关的property、staticmethod、classmethod都是对__ get __ 和__ set __进行的改写
如果实例字典中有与描述符同名的属性,如果描述器是数据描述器,优先使用;如果是非数据描述器,则优先实例字典

obj.__dict__   type(obj).__dict__  type(obj)父类.__dict__ 

4.3上下文管理器

1.with open('test.txt') as f:  #上下文表达式
2.open('test.txt') #上下文管理器

也是就 __ enter __ 和 __ exit __ 的实现

with 也会帮助捕获代码中的异常,在其退出的时候会返回参数exc_type 、exc_val、exc_tb的异常信息

mport contextlib
@contextlib.contextmanager
def open_func(file_name):
 # __enter___
 print('open file:', file_name, 'in __enter__')
 file_handler = open(file_name, 'r')
 
 # ̓yield
 yield file_handler
 # __exit__
 print('close file:', file_name, 'in __exit__')
 file_handler.close()
 return
with open_func('/Users/MING/mytest.txt') as file_in:
 for line in file_in:
 print(line)

5.5自带缓存

适用于3.2+ 以后

from functools import lru_cache

@lru_cache(None)
def add(x, y):
    print("calculating: %s + %s" % (x, y))
    return x + y


print(add(1, 2))
print(add(1, 2))#直接调用结果
print(add(2, 3))
print(add(1, 2))

只会在内存溢出的时候被释放,设置参数max_size

5.6 流式读取大文件

from functools import partial


def read_from_file(f_name, block_size=1024 * 8):
    with open(f_name, "rb") as fp:
        while True:
            chunk = fp.read(block_size)
            if not chunk:
                break
            yield chunk


def read_from_file01(f_name, block_size=1024 * 8):#通过设置block_size 来控制读取的大小
    with open(f_name, "rb") as fp:
        for chunk in iter(partial(fp.read, block_size), b''):  # 如果iterator的_next_() 等于 b”“,则会stopiteration
            # if not chunk:
            #     break
            yield chunk


if __name__ == '__main__':
    content = read_from_file01("test_file.txt")
    print(content)
    for i in content:
        print(i)

5.7 defer延迟调用

golang 中的defer 能在外部函数返回后,再执行内部函数。称为延迟调用

import "fmt"
func myfunc() {
 fmt.Println("B")
}
func main() {
 defer myfunc()
 fmt.Println("A")
}

在python中使用上下文管理器来实现延迟调用

5.9重定向标准输出到日志

"""
只会在Linux下生效
将程序中的标准输出记录为日志
"""

import contextlib
import sys

log_file = "./my_log"


def you_task():
    print("good")
    pass


@contextlib.contextmanager
def close_stdout():
    raw_stdout = sys.stdout
    f = open(log_file, "a+")
    sys.stdout = f

    yield

    sys.stdout = raw_stdout
    f.close()


with close_stdout():
    you_task()

5.11 程序退出后执行

atexit.register(clean_1, ݇1, ݇2, ݇3='xxx')
import atexit
@atexit.register
def clean():
	print("do some clean")

def main():
	1/0
	
main()

局限

1.程序是被你没有处理过的信号杀死,无法执行

2.严重的python内部错误,无法执行

3.手动调用os._exit(),无法执行

5.13

通过程序查询源码

improt inspect
def addd(x,y):
	retrn x + y
	
print(inspect.getsource(addd))

5.14重试

from tenacity import retry
@retry()
@retry(wait=wait_fixed(2))
@retry(stop=stop_after_attempt(7))
@retry(stop=stop_after_delay(10))
@retry(stop=(stop_after_delay(10) | stop_after_attempt(7)))
@retry(retry=retry_if_exception_type(exceptions.Timeout))
@retry(stop=stop_after_attempt(3),retry=retry_if_result(is_false))
@retry(stop=stop_after_attempt(7), reraise=True)
@retry(stop=stop_after_attempt(3),retry_error_callback=return_last_value,
 retry=retry_if_result(is_false))
def test_retry():
 print("重试")
 raise Exception #出现错误进行重试
test_retry()

5.20 else的用法

for else 当for没有被beak,则执行else

try else 当try没有捕获到异常,则执行else

5.21单分派函数

PEP 443 – Single-dispatch generic functions | peps.python.org

单分派函数:根据第一个函数入参的不同类型,来选择不通的调用函数
多分派函数:根据多个参数的类型专门选择函数的行为
泛函数:多个函数绑在一起组合成一个泛函数

from functools import singledispatch


@singledispatch
def age(obj):
    print('请输入合法参数')


@age.register(int)
def _(age):
    print('我已经{}了'.format(age))


@age.register(str)
def _(age):
    print('I am {} years old.'.format(age))


age(23)  # int
age('twenty three')  # str
age(['23'])  # list

6.1 不要直接调用私有方法

如果想调用

ins._class__fun()

6.2 默认参数

可变,默认,关键字

函数的默认参数不应该为可变参数,如下item_list默认值为列表对象

def func(item, item_list=[]):
 item_list.append(item)
 print(item_list)
func('iphone')
func('xiaomi', item_list=['oppo','vivo'])
func('huawei')
第一次调用 将iphone 放入新建列表1 输出iphone
第二次调用  新建列表2其中有oppo和vivo,再将xiaomi放入列表2
第三次调用 函数直接找到默认列表1 位置,将huawei放入

在函数第一次初始化的def的时候,先生成这个默认参数为可变对象的内存地址,这个默认参数将与这个地址绑定。接下来如果默认参数有新值,则使用新的地址(列表2);无新值,则仍然使用原来的地址(列表1)

6.3 增量运算符号

+= 背后的魔法方法是 __iadd__,如果没有实现这个方法则会退而求其次使用 __add__

7.1python lib

python常用热度比较高的库
GitHub - iswbm/awesome-python-cn: Python资源大全中文版,包括:Web框架、网络爬虫、模板引擎、数据库、数据可视化、图片处理等,由伯乐在线持续更新。

paramiko ssh连接库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值