intermediate


本文基于Intermediate Python学习过程中摘要与实践。
感谢此书作者,书的更新日期:Jul 11, 2020.

blueprint-(伪代码)
parentheses-(括号)
clause-(从句)

*args and **kwargs

When you do not know beforehand how many arguments can be passed to your function,
use it:

def test_var_args(f_arg,*argv):
    print("first normal arg:",f_arg)
    for arg in argv:
        print("another arg through *argv:",arg)
test_var_args('python','hello','wow')

#-->first normal arg: python
#-->another arg through *argv: hello
#-->another arg through *argv: wow
def test_args_kwargs(arg1,arg2,arg3):
    print("arg1:",arg1)
    print("arg2:",arg2)
    print("arg3",arg3)
kwargs={"arg3":3,"arg2":"two","arg1":5}
test_args_kwargs(**kwargs)

#-->arg1: 5
#-->arg2: two
#-->arg3 3

*args is used to send a non-keyworded variable length argument list to the function.
**kwargs allows you to pass keyworded variable length of arguments to a function.
The order is some_func(fargs, *args, **kwargs)

The most common use case is when making function decorators.

Debugging

You can run a script from the commandline using the Python debugger(pdb). Here is an example:
$ python -m pdb my_script.py
Running from inside a script:

import pdb
def make_bread():
    pdb.set_trace()
    return  " i dont have time"
print(make_bread())

You would enter the debugger pattern as soon as you run it. Now it’s time to learn some of the commands of the debugger.
Commands:

  • c: continue execution

  • w: shows the context of the current line it is executing.

  • a: print the argument list of the current function

  • s: execute the current line and stop at the first possible occasion

  • n: continue execution until the next line in the current function is reached or it returns

Generators

According to Wikipedia, an iterator is an object that enables a programmer to traverse a container, particularly lists.

可迭代对象

An iterable is any object in Python which has an __iter__ or a __getitem__ method
defined which returns an iterator or can take indexes.

迭代器

An iterator is any object in Python which has a __next__ method defined.

迭代

When we use a loop to loop over something it is called iteration.

生成器
  • Generators are iterators, but you can only iterate over them once.
  • It’s because they do not store all the values in memory, they generate the values on the fly.
  • Most of the time generators are implemented as functions.
def generator_function():
    for i in range(10):
        yield i
for item in generator_function():
    print(item)
def generator_function():
    for i in range(2):
        yield i
gen = generator_function()
print(next(gen))  #-->0
print(next(gen))  #-->1
print(next(gen))  #-->error

# after yielding all the values next() caused a StopIteration error
my_string = "Yasoob"
my_iter = iter(my_string)
next(my_iter)

# str是个可迭代对象,但不是迭代器
# 用iter()函数

Map, Filter and Reduce

菜鸟教程链接:map filter reduce

items = [1, 2, 3, 4, 5]
squared = []
for i in items:
    squared.append(i**2)
#       ||
#       ||
#       \/
items = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, items))
def multiply(x):
    return (x*x)
def add(x):
    return (x+x)
funcs = [multiply, add]
for i in range(5):
    value = list(map(lambda x: x(i), funcs))

# use map even a list of functions
number_list = range(-5, 5)
less_than_zero = list(filter(lambda x: x < 0, number_list))
print(less_than_zero)

#-->[-5, -4, -3, -2, -1]

#If map & filter do not appear beautiful to you
# then you can read about list/dict/tuple comprehensions.(推导式)
product = 1
list = [1, 2, 3, 4]
for num in list:
    product = product * num
#       ||
#       ||
#       \/
from functools import reduce
product = reduce((lambda x, y: x * y), [1, 2, 3, 4])

Decorators

Decorators are a significant part of Python. In simple words: they are functions which modify the functionality of other functions. They help to make our code shorter and more Pythonic.

def hi(name="yasoob"):
    return "hi " + name
print(hi())
# output: 'hi yasoob'
# 我们甚⾄可以将⼀个函数赋值给⼀个变量,⽐如
greet = hi
# 我们这⾥没有在使⽤⼩括号,因为我们并不是在调⽤hi函数
# ⽽是在将它放在greet变量⾥头。我们尝试运⾏下这个
print(greet())
# output: 'hi yasoob'
# 如果我们删掉旧的hi函数,看看会发⽣什么!
del hi
print(hi())
#outputs: NameError
print(greet())
#outputs: 'hi yasoob'

# ======Everything in python is a object=====
def hi(name="yasoob"):
    def greet():
        return "now you are in the greet() function"
    def welcome():
        return "now you are in the welcome() function"
    if name == "yasoob":
        return greet
    else:
        return welcome
a = hi()
print(a)
#-->function greet at 0x7f2143c01500>
#上⾯清晰地展示了`a`现在指向到hi()函数中的greet()函数
#现在试试这个
print(a())
#-->now you are in the greet() function

#=====在函数中定义函数,返回函数=====
def hi():
    return "hi yasoob!"
def doSomethingBeforeHi(func):
    print("I am doing some boring work before executing hi()")
    print(func())
doSomethingBeforeHi(hi)
#-->I am doing some boring work before executing hi()
# hi yasoob!

#=====将函数作为参数传给另一个函数=====
def a_new_decorator(a_func):
    def wrapTheFunction():
        print("I am doing some boring work before executing a_func()")
        a_func()
        print("I am doing some boring work after executing a_func()")
    return wrapTheFunction
def a_function_requiring_decoration():
    print("I am the function which needs some decoration")

a_function_requiring_decoration()
#outputs: "I am the function which needs some decoration"
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
#now a_function_requiring_decoration is wrapped by wrapTheFunction()
a_function_requiring_decoration()
#outputs:I am doing some boring work before executing a_func()
# I am the function which needs some decoration
# I am doing some boring work after executing a_func()

###一个简单的装饰器,相当于赋给函数一个经修饰的函数
@a_new_decorator
def a_function_requiring_decoration():
    print("I am the function which needs some decoration")
a_function_requiring_decoration()
#outputs: I am doing some boring work before executing a_func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func()

#重点理解一下 @ 符号

#但此时a_function_requiring_decoration.__name__变成了wrapTheFunction
#这时就有了functools.wraps,下面是蓝本:
# blueprint
from functools import wraps
def decorator_name(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if not can_run: 
            return "Function will not run"
        return f(*args, **kwargs)
    return decorated
@decorator_name
def func():
    return("Function is running")

can_run = True
print(func())
# Output: Function is running
can_run = False
print(func())
# Output: Function will not run

Mutation

foo = ['hi']
print(foo)
#-->['hi']

bar = foo
bar += ['bye']
print(foo)
#-->['hi', 'bye']

#将一个变量赋值为另一个可变类型变量时,对数据的改动会反映在两个变量上

#python可变类型(mutable):列表,字典
#python不可变类型:数字,字符串,元组
def add_to(num, target=[]):
    target.append(num)
    return target
add_to(1)
# Output: [1]
add_to(2)
# Output: [1, 2]
add_to(3)
# Output: [1, 2, 3]

#在Python中当函数被定义时,默认参数只会运算⼀次

Enumerate

my_list = ['apple', 'banana', 'grapes', 'pear']
for index,name in enumerate(my_list,1):
    print index,name

# Output:
# 1 apple
# 2 banana
# 3 grapes
# 4 pear

Object introspection

dir(object)
# It returns a list of attributes and methods belonging to an object

type(object)
# It returns the type of an object.

id(object)
# It returns the unique ids of various objects.

异常处理

try:
    file = open('test.txt', 'rb')
except Exception:
    # 打印⼀些异常⽇志,如果你想要的话
    raise

# try/else 在try不出现异常时触发

Classes

class Cal(object):
    # pi is a class variable
    pi = 3.142
    def __init__(self, radius):
        # self.radius is an instance variable
        self.radius = radius
    def area(self):
        return self.pi * (self.radius ** 2)

a = Cal(32)
a.area()
# Output: 3217.408
a.pi
# Output: 3.142
a.pi = 43
a.pi
# Output: 43

b = Cal(44)
b.area()
# Output: 6082.912
b.pi
# Output: 3.142
b.pi = 50
b.pi
# Output: 50

Function caching

from functools import lru_cache
@lru_cache(maxsize=32)
def fib(n):
    if n<2:return n
    return fib(n-1)+fib(n-2)
print([fib(n) for n in range(40)])

fib.cache_clear()


#这是一个被相同参数频繁调用的I/O密集的函数
#使用lru_cache可以使这段代码的运行时间从53.6s变为0s(笔者自测)

结语

本文漏掉了set结构 Ternary Operators(三元运算符) 装饰器的高级应用
Global & Return(尽量return多值代替global)
__slots__魔法 Virtual Environment Collections
推导式 lambda 参数:操作 Python C extensions
for/else(else会在for循环正常结束时执行)
open函数 Targeting Python 2+3 Coroutines(协程)
上下文管理器

唔,终于弄完了😀————————2020.8.9


文章作者: ╯晓~
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ╯晓~ !
评论
  目录