第十八-十九章 Functions and Generators
来源:互联网 发布:网络电影 编辑:程序博客网 时间:2024/06/04 18:27
第十八章 Arguments
1.Argument-Passing Basics
- Arguments are passed by automatically assigning objects to local variable names.
- Assigning to argument names inside a function does not affect the caller.
- Changing a mutable object argument in a function may impact the caller.
Argument Matching Basics:
- Positionals: matched from left to right
- Keywords: matched by argument name
- Defaults: specify values for optional arguments that aren’t passed
- Varargs collecting: collect arbitrarily many positional or keyword arguments
- Varargs unpacking: pass arbitrarily many positional or keyword arguments
- Keyword-only arguments: arguments that must be passed by name
The Gritty Details:
- In a function call, arguments must appear in this order: any positional arguments
(value); followed by a combination of any keyword arguments (name=value) and
the *iterable form; followed by the **dict form. - In a function header, arguments must appear in this order: any normal arguments
(name); followed by any default arguments (name=value); followed by the *name (or
* in 3.X) form; followed by any name or name=value keyword-only arguments (in
3.X); followed by the **name form.
参数匹配:
- Assign nonkeyword arguments by position
- Assign keyword arguments by matching names.
- Assign extra nonkeyword arguments to *name tuple.
- Assign extra keyword arguments to **name dictionary.
- Assign default values to unassigned arguments in header.
def f(a,b,c): print(a,b,c)f(1,2,3)f(c=3,b=2,a=1)f(1,c=3,b=2)f(3,a=1,b=2)# f(b=3,c=4,1) SyntaxError: non-keyword arg after keyword arg
>>> ================================ RESTART ================================>>> 1 2 31 2 31 2 3Traceback (most recent call last): File "D:\test.py", line 10, in <module> f(3,a=1,b=2)TypeError: f() got multiple values for argument 'a'
Arbitrary Arguments Examples:
Headers: Collecting arguments
>>> def f(*args): print(args) #collects unmatched positional arguments into a tuple>>> f()()>>> f(1)(1,)>>> f(1, 2, 3, 4)(1, 2, 3, 4)>>> def f(**args): print(args) #works for keyword arguments,collects them into a new dictionary>>> f(){}>>> f(a=1, b=2){'a': 1, 'b': 2}>>> def f(a, *pargs, **kargs): print(a, pargs, kargs)>>> f(1, 2, 3, x=1, y=2)1 (2, 3) {'y': 2, 'x': 1}Calls: Unpacking arguments
注意:one star means positionals, and two applies to keywords.
Python 3.X Keyword-Only Arguments
>>> def kwonly(a, *b, c): #参数c只能用Keyword传参 print(a, b, c)>>> kwonly(1, 2, c=3)1 (2,) 3>>> kwonly(a=1, c=3)1 () 3>>> kwonly(1, 2, 3)TypeError: kwonly() missing 1 required keyword-only argument: 'c'
>>> def kwonly(a, *, b, c): #does not accept a variable-length argument list but still expects all arguments following the * to be passed as keywordsprint(a, b, c)>>> kwonly(1, c=3, b=2)1 2 3>>> kwonly(c=3, b=2, a=1)1 2 3>>> kwonly(1, 2, 3)TypeError: kwonly() takes 1 positional argument but 3 were given>>> kwonly(1)TypeError: kwonly() missing 2 required keyword-only arguments: 'b' and 'c'
Ordering rules:
keyword-only arguments must be specified after a single star, not two
>>> def kwonly(a, **pargs, b, c):SyntaxError: invalid syntax>>> def kwonly(a, **, b, c):SyntaxError: invalid syntax>>> def f(a, *b, **d, c=6): print(a, b, c, d) # Keyword-only before **!SyntaxError: invalid syntax>>> def f(a, *b, c=6, **d): print(a, b, c, d) # Collect args in header>>> f(1, 2, 3, x=4, y=5) # Default used1 (2, 3) 6 {'y': 5, 'x': 4}>>> f(1, 2, 3, x=4, y=5, c=7) # Override default 注意与下面对比1 (2, 3) 7 {'y': 5, 'x': 4}>>> f(1, 2, 3, c=7, x=4, y=5) # Anywhere in keywords1 (2, 3) 7 {'y': 5, 'x': 4}>>> def f(a, c=6, *b, **d): print(a, b, c, d) # c is not keyword-only here!>>> f(1, 2, 3, x=4)1 (3,) 2 {'x': 4}
function calls: when keyword-only arguments are passed, they must appear before a **args form.
keyword-only argument can be coded either before or after the *args, though, and may be included in **args:
>>> def f(a, *b, c=6, **d): print(a, b, c, d) # KW-only between * and **>>> f(1, *(2, 3), **dict(x=4, y=5)) # Unpack args at call1 (2, 3) 6 {'y': 5, 'x': 4}>>> f(1, *(2, 3), **dict(x=4, y=5), c=7) # Keywords before **args!SyntaxError: invalid syntax>>> f(1, *(2, 3), c=7, **dict(x=4, y=5)) # Override default1 (2, 3) 7 {'y': 5, 'x': 4}>>> f(1, c=7, *(2, 3), **dict(x=4, y=5)) # After or before *1 (2, 3) 7 {'y': 5, 'x': 4}>>> f(1, *(2, 3), **dict(x=4, y=5, c=7)) # Keyword-only in ** 也可在**中1 (2, 3) 7 {'y': 5, 'x': 4}
def minmax(test, *args): res = args[0] for arg in args[1:]: if test(arg, res): res = arg return resdef lessthan(x, y): return x < y # See also: lambdadef grtrthan(x, y): return x > yprint(minmax(lessthan, 4, 2, 1, 5, 6, 3)) # Self-test codeprint(minmax(grtrthan, 4, 2, 1, 5, 6, 3))
def sumtree(L): tot = 0 for x in L: # For each item at this level if not isinstance(x, list): tot += x # Add numbers directly else: tot += sumtree(x) # Recur for sublists return totL = [1, [2, [3, 4], 5], 6, [7, 8]] # Arbitrary nestingprint(sumtree(L)) # Prints 36# Pathological casesprint(sumtree([1, [2, [3, [4, [5]]]]])) # Prints 15 (right-heavy)print(sumtree([[[[[1], 2], 3], 4], 5])) # Prints 15 (left-heavy)
# breadth-first by items: add to enddef sumtree(L): # Breadth-first, explicit queue tot = 0 items = list(L) # Start with copy of top level while items: trace(items) front = items.pop(0) # Fetch/delete front item if not isinstance(front, list): tot += front # Add numbers directly visit(front) else: items.extend(front) # <== Append all in nested list return totL = [1, [2, [3, 4], 5], 6, [7, 8]] # Arbitrary nestingprint(sumtree(L)) # Prints 36# Pathological casesprint(sumtree([1, [2, [3, [4, [5]]]]])) # Prints 15 (right-heavy)print(sumtree([[[[[1], 2], 3], 4], 5])) # Prints 15 (left-heavy)print('-'*40)# depth-first by items: add to front (like recursive calls version)def sumtree(L): # Depth-first, explicit stack tot = 0 items = list(L) # Start with copy of top level while items: trace(items) front = items.pop(0) # Fetch/delete front item if not isinstance(front, list): tot += front # Add numbers directly visit(front) else: items[:0] = front # <== Prepend all in nested list return totL = [1, [2, [3, 4], 5], 6, [7, 8]] # Arbitrary nestingprint(sumtree(L)) # Prints 36# Pathological casesprint(sumtree([1, [2, [3, [4, [5]]]]])) # Prints 15 (right-heavy)print(sumtree([[[[[1], 2], 3], 4], 5])) # Prints 15 (left-heavy)print('-'*40)
Function Objects: Attributes and Annotations:
annotations work only in def statements, not lambda expressions
def func(a: 'spam', b: (1, 10), c: float) -> int: return a + b + c>>> func.__annotations__{'return': <class 'int'>, 'c': <class 'float'>, 'a': 'spam', 'b': (1, 10)}>>> def func(a: 'spam' = 4, b: (1, 10) = 5, c: float = 6) -> int: #使用默认值 return a + b + c>>> def func(a:'spam'=4, b:(1,10)=5, c:float=6)->int: #空格可有可无 return a + b + c
Anonymous Functions: lambda:
lambda Basics:lambda argument1, argument2,... argumentN : expression using arguments
- lambda is an expression, not a statement.
- lambda’s body is a single expression, not a block of statements.
>>> def func(x, y, z): return x + y + z>>> func(2, 3, 4)9>>> f = lambda x, y, z: x + y + z # f is assigned the function object the lambda expression creates>>> f(2, 3, 4)9lambda expressions introduce a local scope much like a nested def, which automatically
sees names in enclosing functions, the module, and the built-in scope (via the
LEGB rule,
L = [lambda x: x ** 2, # Inline function definition lambda x: x ** 3, lambda x: x ** 4] # A list of three callable functionsfor f in L: print(f(2)) # Prints 4, 8, 16print(L[0](3)) # Prints 9
lambda内使用循环时,方法一使用map,方法二 list comprehension expressions
>>> import sys>>> showall = lambda x: list(map(sys.stdout.write, x)) # 3.X: must use list>>> t = showall(['spam\n', 'toast\n', 'eggs\n']) # 3.X: can use printspamtoasteggs>>> showall = lambda x: [sys.stdout.write(line) for line in x]>>> t = showall(('bright\n', 'side\n', 'of\n', 'life\n'))brightsideoflife>>>
import sysfrom tkinter import Button, mainloop # Tkinter in 2.Xx = Button(text='Press me',command=(lambda:sys.stdout.write('Spam\n'))) # 3.X: print()x.pack()mainloop() # This may be optional in console mode
Mapping Functions over Iterables: map
>>> counters = [1, 2, 3, 4]>>> def inc(x): return x + 10 # Function to be run>>> list(map(inc, counters)) # Collect results[11, 12, 13, 14]>>> list(map((lambda x: x + 3), counters)) # Function expression[4, 5, 6, 7]>>> pow(3, 4) # 3**481>>> list(map(pow, [1, 2, 3], [2, 3, 4])) # 1**2, 2**3, 3**4[1, 8, 81]Selecting Items in Iterables: filter
>>> list(filter((lambda x: x > 0), range(−5, 5))) # An iterable in 3.X[1, 2, 3, 4]
Combining Items in Iterables: reduce
>>> from functools import reduce # Import in 3.X, not in 2.X>>> reduce((lambda x, y: x + y), [1, 2, 3, 4])10>>> reduce((lambda x, y: x * y), [1, 2, 3, 4])24
0 0
- 第十八-十九章 Functions and Generators
- 第二十~章 Functions and Generators
- 第十六-十七章 Functions and Generators
- yield and Generators
- Working with promise and generators
- Generators
- 第十八章
- 第十八章
- Useful HTML5 Frameworks, Template Generators and Tools
- Improve Your Python: 'yield' and Generators Explained
- Iterables, Iterators and Generators: Part 2
- Improve Your Python: 'yield' and Generators Explained
- 山海演武传·黄道·第一卷 雏龙惊蛰 第十八 ~ 十九章 煌煌金麟不夜城
- Stored Procedures and Functions
- URL functions and classes
- jquery selectors and functions
- JQuery Callback and Functions
- Plugin file and functions
- Storm详解二、写第一个Storm应用
- poj 1631
- STARTUPINFO
- P153 1
- 一种开辟多维数组的方法
- 第十八-十九章 Functions and Generators
- 第三章习题T3
- python3.4多线程实现同步的四种方式(锁机制、条件变量、信号量和同步队列)
- (2014.4.24)server/client代码
- OpenMP(3) omp_get_wtime 函数
- 黑马程序员:多态和内部类
- 第七题
- sicily 1021 couples
- JS中setTimeout()的用法详解