1.符号表

执行一个函数会引入一个用于函数的局部变量的新符号表。

更确切地说,

函数中的所有的赋值都是将值存储在局部符号表;

而变量引用首先查找局部符号表,

然后是上层函数的局部符号表,

然后是全局符号表,

最后是内置名字表。

 

global语句中命名),虽然可以引用它们。

 

 

2.传值

函数调用的实际参数在函数被调用时引入被调函数的局部符号表;

因此,

参数的传递使用传值调用

(这里的值始终是对象的引用,不是对象的值)。

一个函数调用另一个函数时,

会为该调用创建一个新的局部符号表。

函数定义会在当前符号表内引入函数名。

函数名对应值的类型是解释器可识别的用户自定义函数。

此值可以分配给另一个名称,

然后也可作为函数。

这是通用的重命名机制:

传参:默认值在定义域中的函数定义的时候计算

 

重要的警告:

默认值只计算一次。

这使得默认值是列表、字典或大部分类的实例时会有所不同。

例如,

下面的函数在后续调用过程中会累积传给它的参数:

def f(a, L=[]):
    L.append(a)
    return L

print f(1)
print f(2)
print f(3)

这将会打印

[1]
[1, 2]
[1, 2, 3]

如果你不想默认值在随后的调用中共享,

可以像这样编写函数:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

 

**name形式出现时,

映射类型 — 字典),

该字典包含了所有未出现在形式参数列表中的关键字参数。

*name形式的参数(在下一小节中所述)组合使用,

*name接收一个包含所有没有出现在形式参数列表中的位置参数元组。

**name之前。)

例如,

如果我们定义这样的函数:

def cheeseshop(kind, *arguments, **keywords):
    print "-- Do you have any", kind, "?"
    print "-- I'm sorry, we're all out of", kind
    for arg in arguments:
        print arg
    print "-" * 40
    keys = sorted(keywords.keys())
    for kw in keys:
        print kw, ":", keywords[kw]

它可以这样调用:

cheeseshop("Limburger", "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper='Michael Palin',
           client="John Cleese",
           sketch="Cheese Shop Sketch")

当然它会打印:

-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch

注意在打印关键字参数之前,

keys() 方法的结果进行排序,

生成了关键字参数名的列表;

如果不这样做,

打印出来的参数的顺序是未定义的。

 

 

3.过程和函数的区别

如果你使用过其他语言,你可能会反对说:

fib不是一个函数,而是一个过程(子程序),

因为它并不返回任何值。

return语句的函数也返回一个值,尽管是一个很无聊的值。

None(它是一个内置的名称)。

None只是唯一的输出,解释器通常不会打印出来。

print 语句。

 

4.参数拆分

参数列表的分拆

当传递的参数已经是一个列表或元组时,

情况与之前相反,

你要分拆这些参数,

因为函数调用要求独立的位置参数。

例如,

range()函数期望单独的start和stop参数。

如果它们不是独立的,

*-操作符将参数从列表或元组中分拆开来:

>>>
>>> range(3, 6)             # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args)            # call with arguments unpacked from a list
[3, 4, 5]

**-操作符让字典传递关键字参数:

>>>
>>> def parrot(voltage, state='a stiff', action='voom'):
...     print "-- This parrot wouldn't", action,
...     print "if you put", voltage, "volts through it.",
...     print "E's", state, "!"
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

5.lambda匿名小函数

lambda关键字创建小的匿名函数。

下面这个函数返回它的两个参数的和:

a + b

Lambda 函数可以用于任何需要函数对象的地方。

在语法上,它们被局限于只能有一个单独的表达式。

在语义上,他们只是普通函数定义的语法糖。

像嵌套的函数定义,lambda 函数可以从包含范围引用变量:

def make_incrementor(n):
...     return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43

上面的示例使用 lambda 表达式返回一个函数。

另一个用途是将一个小函数作为参数传递:

>>>
>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

 

 

 

6.文档字符串

这一行应该以大写字母开头,并以句号结尾。

以下各行应该是一段或多段描述对象的调用约定、 其副作用等。

留白的长度应当等于扩展制表符的宽度(正常是 8 个空格)。

这里是一个多行文档字符串的示例:

>>>
>>> def my_function():
...     """Do nothing, but document it.
...
...     No, really, it doesn't do anything.
...     """
...     pass
...
>>> print my_function.__doc__
Do nothing, but document it.

    No, really, it doesn't do anything.

 

 

 

相关文章:

  • 2021-04-15
  • 2022-12-23
  • 2021-08-09
  • 2022-12-23
  • 2022-02-25
  • 2022-12-23
  • 2021-09-16
  • 2021-09-15
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-02-11
  • 2021-08-13
  • 2021-04-19
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案