cs61a-week2笔记

本文详细介绍了Python中的函数定义、参数传递、自定义函数、命名规则、控制结构(如条件语句和迭代)、测试方法(断言和doctest)、高阶函数(嵌套函数、lambda表达式和函数装饰器)等内容,为初学者提供了深入理解Python语言的关键概念和实践指导。
摘要由CSDN通过智能技术生成

1函数

1.1 定义函数

def <名称>(<形式参数>): 
    return <返回表达式>

①<形式参数>是以逗号分隔命名的列表。
②第二行必须缩进。
③返回时表达值不会立即计算,在最终调用函数才计算。
④纯函数(最好)可以作为定义其他函数的构建块

def  sum_squares ( x ,  y ): 
    return add ( square ( x ), square ( y ))

函数的名称会重复两次,一次在定义框架中,另一次作为函数本身被调用的一部分。

1.2 函数赋值

def语句和赋值语句都将名称绑定到值,并且任何现有的绑定都会丢失。
例如,下面的g首先指的是无参数的函数,然后是数字,然后是拥有两个参数的新函数。

>>> def g():
        return 1
>>> g()
1
>>> g = 2
>>> g
2
>>> def g(h, i):
        return h + i
>>> g(1, 2)
3

1.3 自定义函数

新的framework,不再是global framework。该framework只能由该函数访问。
①整个函数的def语句是在一个步骤中处理的。
②函数只有在调用的时候才执行,而不是定义的时候
③里面的形参是在新的framework下。在全局中定义的参数才在global framework。函数名在global framework
④每次调用函数时都会引入一个新的本地framework,调用完framework就删掉,即使同一函数被调用两次也是如此。
⑤调用函数时输入的第一个值,跟定义函数时第一个形参绑定。

# eg.
def improve(update, close, guess=1):...
improve(sqrt_update, sqrt_close)
# 在这里,sqrt_update()(值)与update(名称)绑定

⑥不同本地框架中x的绑定是不相关的。计算模型经过精心设计以确保这种独立性。
⑦函数体内的赋值语句不能影响全局框架。函数只能操纵其本地环境。
⑧return表达式的值是正在应用的函数的返回值。
在这里插入图片描述

1.4 命名规则

①函数名称小写,单词间“_”连接
②不用print add max命名
③当作用明显时,可以使用单字母参数名称,但应避免使用“l”(小写 ell)、“O”(大写 oh)或“I”(大写 i),以避免与数字混淆
④重要tips!!!学会拆分功能!
每个功能都应该只有一项工作。该工作应该可以通过一个简短的名称来识别,并可以用一行文本来描述。依次执行多项作业的函数应划分为多个函数。

一个例子

def pressure(v, t, n=6.022e23):
    """Compute the pressure in pascals of an ideal gas.

    v -- volume of gas, in cubic meters
    t -- absolute temperature in degrees kelvin
    n -- particles of gas (default: one mole)
    """
    k = 1.38e-23  # Boltzmann's constant
    return n * k * t / v

2 控制

2.1 条件语句

···
if <表达式>:
<套件>
elif <表达式>:
<套件>
else:
<套件>
···

布尔值

True 真值
False 假值:0、None、和布尔值False

布尔值内置比较操作符>、<、>=、<=、==、!=
**注意!赋值 ( = ) 与相等比较 ( == )

比较语句:

x > 0 and sqrt(x) > 10
n == 0 or 1/n != 0.0
## 2.2 迭代(重复)
#### while
```python
while k < n:
    pred, curr = curr, pred + curr
     k = k + 1

不终止的while语句称为无限循环。按<Control>-C强制 Python 停止循环。

2.3测试

断言

assert  fib ( 8 )  ==  13, 'The 8th Fibonacci number should be 13'
def fib_test():
    #......
    assert fib(2) == 1, 'The 2nd Fibonacci number should be 1'
    assert fib(3) == 1, 'The 3rd Fibonacci number should be 1'
    assert fib(50) == 7778742049, 'Error at the 50th Fibonacci number'

断言的表达式的计算结果为真值时,执行断言语句不起作用。当它是假值时,断言会导致错误并停止执行。

文档测试

可以将简单的测试直接放置在函数的文档字符串中。
文档字符串的第一行应包含函数的单行描述,后跟一个空行。随后可能会详细描述参数和行为。此外,文档字符串可能包括调用该函数的示例交互式会话:

>>> def sum_naturals(n):
        """Return the sum of the first n natural numbers.

        >>> sum_naturals(10)
        55
        >>> sum_naturals(100)
        5050
        """
        total, k = 0, 1
        while k <= n:
            total, k = total + k, k + 1
        return total

然后,可以通过doctest 模块验证交互。

(全局函数版)
>>> from doctest import testmod
>>> testmod()
TestResults(failed=0, attempted=2)
(单个函数版)

第一个参数是要测试的函数。第二个应该始终是表达式 globals()的结果,这是一个返回全局环境的内置函数。第三个参数为True表示我们想要“详细”输出:所有运行的测试的目录。

>>> from doctest import run_docstring_examples
>>> run_docstring_examples(sum_naturals, globals(), True)
Finding tests in NoName
Trying:
    sum_naturals(10)
Expecting:
    55
ok
Trying:
    sum_naturals(100)
Expecting:
    5050
ok

在文件中编写 Python 时,可以通过使用 doctest 命令行选项启动 Python 来运行文件中的所有 doctest:

python3 -m doctest <python_source_file>

3 高阶函数

3.1嵌套函数

def sqrt(a):
        def sqrt_update(x):
            return average(x, a/x)
        def sqrt_close(x):
            return approx_eq(x * x, a)
        return improve(sqrt_update, sqrt_close)

在这里,framework的嵌套关系是:
在这里插入图片描述
即,层层嵌套关系

3.2用于返回值的函数

def compose1(f, g):
        def h(x):
            return f(g(x))
        return h

3.3lambda表达式

在 Python 中,我们可以使用lambda 表达式动态创建函数值,该表达式的计算结果为未命名函数。
特点:
①计算结果是一个函数!未命名函数!
②此函数返回一个表达式。
③不允许赋值和控制语句。
④lambda的简写:左边是输入的值,右边是有返回值的函数的返回值表达式

compose1  =  lambda  f , g :  lambda  x :  f ( g ( x ))

上式就等价于以下的example1

# example1
def compose1(f, g):
        return lambda x: f(g(x))
## take x and return f(g(x))

# example2
>>> s = lambda x: x * x
>>> s
<function <lambda> at 0xf3f490>
>>> s(12)
144

# example3
def compose1(f, g):
    return lambda x: f(g(x))
f = compose1(lambda x: x * x, lambda y: y + 1)
result = f(12)
result
#output:169     即(12+1)*(12+1)

# example4
def inverse(f):  ## 用lambda多简洁!
    """Return a function g(y) that returns x such that f(x) == y.
    >>> sqrt = inverse(square)
    >>> sqrt(16)
    4
    """
    return lambda y: search(lambda x: f(x) == y)

思考:用lambda和不用的区别是?

square = x * x
square = lambda x: x * x

3.4 函数装饰器

@trace是注释,会影响def的执行规则。

>>> def trace(fn):
        def wrapped(x):
            print('-> ', fn, '(', x, ')')  ## 对比下面
            return fn(x)
        return wrapped
>>> @trace
    def triple(x):
        return 3 * x
>>> triple(12)
->  <function triple at 0x102a39848> ( 12 )    ## 看这里!它已经有了trace函数返回值的属性了!
36

在上面的例子里,名称triple不与该函数绑定,而是绑定到调用trace函数返回函数值的新定义的triple上。等价于:

>>> def triple(x):
        return 3 * x
>>> triple = trace(triple)
>>> triple
<function trace.<locals>.wrapped at 0x000002B4E64CD3F0>
  • 42
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值