Python 进阶

*args 用法

*args 主要用于函数的定义,可以将不定数量的参数传递给一个函数。
*agrs 是用来发送一个非键值对的可变数量的参数列表给一个函数。

def fun(a, *args):
	print('a:'+ a)
	for i in args:
		print('args:'+i)
fun('a','b','c','d')
# a:a
# args:b
# args:c
# args:d

**kwargs 用法

允许将不定长度的 键值对 作为参数传递给一个函数。

def fun(**kwargs):
	for k, v in kwargs.items():
		print(k, v)
fun(a='1',b='2',c='3')
# a 1
# b 2
# c 3

可迭代对象

迭代对象

  • Python 中的任意对象,只要定义了可以返回一个迭代器的 __iter__ 方法
  • 或者定义了支持下标索引的__getitem__方法
  • 它就是一个可迭代对象
  • 可迭代对象就是能提供迭代器的任意对象

迭代器

iter 可以将一个 可迭代对象 返回一个迭代器对象。

  • 任意对象,只要定义了__next__方法,它就是一个迭代器。
my_string = 'HuWenBo'
my_iter = iter(my_string)
for i in range(4):
	print(next(my_iter))
# H
# u
# W
# e

迭代

  • 就是从某个地方取出一个元素的过程。
  • 当我们使用一个循环来遍历某个对象,这个 过程本身 叫做迭代。

生成器

生成器是一种迭代器,但是只能迭代一次。
因为生成器没有把值存在内存中,而是在运行时生成值。
要么用for循环,或传递给任意可以进行迭代的函数和结构。
大多数并不返回一个值,而是yield一个值。

def fun():
	for i in range(5):
		yield i

for i in fun():
	print(i)
# 0
# 1
# 2
# 3
# 4

Map、Filter、Reduce

能为函数式编程提供便利

Map

会将一个函数映射到一个输入列表的所有元素上
map(fun_apply, list)

items = [1,2,3,4]
result = map(lambda x : x ** 2, items)
print(list(result))
# [1, 4, 9, 16]

Filter

filter 过滤列表中的元素,并且返回一个由所有符合要求的元素所构成的列表。

number_list = range(-5, 5)
result = filter(lambda x: x < 0, number_list)
print(list(result))  
# [-5, -4, -3, -2, -1]

Reduce

当对一个列表进行计算并返回结果时,Reduce十分有用

from functools import reduce
result = reduce(lambda x, y : y * y, [1,2,3,4])
print(result)
# 16

三元运算符

is_ok = True
result = 'yes' if is_ok else 'noe'
print(result)
# yes

装饰器

修改其它函数功能的函数,有助于代码复用。
它们封装一个函数,并且来修改他们之前或之后的行为。
Python 中一切皆对象

from functools import wraps
def out_fun(fun):
	@wraps(fun)	# 当取消这个装饰器,return后函数name就是inner_fun
	def inner_fun(*args, **kwargs):
		if fun.__name__ == 'demo':
			print('fun() name is demo')
			return fun(*args, **kwargs)
		else:
			print('fun() name is not demo')
			return fun(*args, **kwargs)
	return inner_fun

@out_fun
def demo():
	return 'this is demo fun'

print(demo())
# fun() name is demo
# this is demo fun

日志功能

日志是装饰器运用的另一个亮点

from functools import wraps
def logit(func):
	@wraps(func)
	def save_logging(*args, **kwargs):
		print(func.__name__ + 'is called')
		return func(*args, **kwargs)
	return save_logging

@logit
def add_fun(a):
	return a

result = add_fun(2)
print(result)

# add_funis called
# 2

在函数中嵌入装饰器

通过装饰器函数传递参数给函数

from functools import wraps
def logit(logfile='out.log'):
	def logging_fun(func):
		@wraps(func)
		def inner_fun(*agrs, **kwargs):
			log_string = func.__name__ + 'was called'
			print(log_string)
			with open(logfile, 'a') as f:
				f.write(log_string)
			return func(*agrs, **kwargs)
		return inner_fun
	return logging_fun
	
@logit()
def fun1():
	pass

@logit(logfile = 'out1.log')
def fun2():
	pass

fun1()
fun2()

__slots__魔法

Python 中每个类都有实例熟悉,默认情况下 Python 用一个字典来保存一个对象的实例熟悉。
slots 来告诉Python不使用字典,而且只给一个固定集合的属性分配空间。

class MyClass(object):
    __slots__ = ['name', 'identifier']
    def __init__(self, name, identifier):
        self.name = name
        self.identifier = identifier
        self.set_up()

try/else 语句

else从句只会在没有异常的情况下执行,而且它会在finally语句之前执行。

try:
    print('I am sure no exception is going to occur!')
except Exception:
    print('exception')
else:
    # 这里的代码只会在try语句里没有触发异常时运行,
    # 但是这里的异常将 *不会* 被捕获
    print('This would only run if no exception occurs. And an error here '
          'would NOT be caught.')
finally:
    print('This would be printed in every case.')

一行式

一行式内容比较多,参考另一片文章。

官网参考

简易 Web server

快速通过网络共享文件

# Python 2
python -m SimpleHTTPServer

# Python 3
python -m http.server

一行构造器

避免类初始化时大量重复的赋值语句

 class A(object):
        def __init__(self, a, b, c, d, e, f):
            self.__dict__.update({k: v for k, v in locals().items() if k != 'self'})

列表展平

快速展平一个嵌套列表

a_list = [[1, 2], [3, 4], [5, 6]]
print(list(itertools.chain.from_iterable(a_list)))
# Output: [1, 2, 3, 4, 5, 6]

# or
print(list(itertools.chain(*a_list)))
# Output: [1, 2, 3, 4, 5, 6]

使用C扩展

开发者有三种方法可以在自己的Python代码中来调用C编写的函数-ctypes,SWIG,Python/C API。每种方式也都有各自的利弊。

CTypes

Python中的ctypes模块可能是Python调用C方法中最简单的一种。
ctypes模块提供了和C语言兼容的数据类型和函数来加载dll文件,因此在调用时不需对源文件做任何的修改。
正是如此奠定了这种方法的简单性。

SWIG

Python中调用C代码的另一种方法。
在这个方法中,开发人员必须编写一个额外的接口文件来作为SWIG(终端工具)的入口。

Python/C API

Python/C API可能是被最广泛使用的方法。它不仅简单,而且可以在C代码中操作你的Python对象。

协程

生成器是数据的生产者
协程则是数据的消费者

def grep():
	while True:
		line = yield
		print(line)

demo = grep()
next(demo)  # 启动一个协程
demo.send('hello')
demo.send('word')
demo.close()    # 关闭一个协程
# hello
# word

函数缓存

函数缓存允许我们将一个函数对于给定参数的返回值缓存起来。
Python 3.2以后版本,有个lru_cache的装饰器,允许我们将一个函数的返回值快速地缓存或取消缓存。

from functools import lru_cache
@lru_cache(maxsize=30)	# maxsize参数告诉lru_cache缓存最近多少个返回值
def fib(n):
	if n < 2:
		return n
	return fib(n-1) + fib(n-2)
print([fib(n) for n in range(10)])
fib.cache_clear()	# 清空缓存

上下文管理器

上下文管理器的类,要定义__enter____exit__

class File:
    def __init__(self, file_name, method):
        self.file_obj = open(file_name, method)
    def __enter__(self):
        return self.file_obj
    def __exit__(self, type, value, traceback):
        self.file_obj.close()
with File('demo.txt', 'w') as opened_file:
    opened_file.write('Hello!')
  1. with 语句先暂存 File 类的 __exit__ 方法
  2. 然后调用 File 类的 __enter__ 方法
  3. __enter__ 方法打开文件并返回给with语句
  4. 打开的文件句柄被传递给 opened_file 参数
  5. 我们使用 write() 来写文件
  6. with 语句调用之前暂存的 __exit__ 方法
  7. __exit__ 方法关闭了文件
  • 在第4步和第6步之间,如果发生异常,Python会将异常的type,valuetraceback传递给__exit__方法。
  • 当发生异常把异常的type,valuetraceback传递给__exit__方法
  • 如果__exit__返回的是True,异常会被处理,返回的是True之外的,改异常被with语句抛出

基于生成器的实现

装饰器(decorators)和生成器(generators)来实现上下文管理器
我们可以使用一个生成器函数来实现一个上下文管理器
Python有个contextlib模块专门用于这个目的

from contextlib import contextmanager

@contextmanager
def open_file(name):
    f = open(name, 'w')
    yield f
    f.close()
with open_file('demo.txt') as f:
  • 被装饰器装饰的函数分为三部分:
  1. with语句中的代码块执行前执行函数中yield之前代码
  2. yield返回的内容复制给as之后的变量
  3. with代码块执行完毕后执行函数中yield之后的代码

变为上下文对象

  • 如果一个对象没有实现上下文,我们就不能把它用于with语句。这个时候,可以用closing()来把该对象变为上下文对象。
from contextlib import closing
from urllib.request import urlopen

with closing(urlopen('http://httpbin.org/get')) as page:
    for line in page:
        print(line)

closing也是一个经过@contextmanager装饰的generator

@contextmanager
def closing(thing):
    try:
        yield thing
    finally:
        thing.close()

它的作用就是把任意对象变为上下文对象,并支持with语句。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值