cs61A lec2.3 define functions

def square(x):
    return mul(x, x)

这节正式介绍函数定义,但其实之前我们已经使用过↑

赋值是简单abstraction方式,绑定变量到值;

函数定义是更为强大的abstraction方式:绑定名到表达式

本小节正式给出其语法如上↑

函数signature说明了一个函数要用到多少变量;函数主体定义了函数表达的计算过程。

- 然后执行过程第二条强调了语法要缩进哈。

把名字粘到现有框架的那个函数身上。

squirrel means to hide in a safe place. lt's also the longest word in the English language that has only one syllable.就像stata当中的值标签定义一样,一个值标签定义的完成只意味着它可被使用,但还没有被调用(called)

定义之后的工作是调用函数。

调用函数:

  1. 添加局域框架,形成新的环境;
  2. 将函数的正式参数绑定到其在那个局域框架下的变量(parameter←argument,有点抽象)
  3. 在那个新环境当中执行函数主体

通俗说就是函数调用并返回值的过程是如上三步↑。下面进行可视化:

from operator import add,mul
def square(x):
    return mul(x, x)
square(-2)

我们在tutor中输入上小节中的如上函数来进行演示,来对这三步骤进行讲解。

行1得到Global frame;行2-3得到square;

行4square(-2)调用函数:执行行4,得到:

添加局域框架,形成新的环境;

将函数域内的变量值2赋值给函数的正式参数x;

跳回def func的函数签名signiture行——行2,)在新环境当中执行函数主体,得到返回值4,以上是调用函数行执行过程所发生的事情。

~和C语的函数创建及调用思路相似

annotate v. 注释

我们对部分重要内容进行注释,可以看到图中有内置函数和用户定义函数,它俩差不多,除了自定义函数有个参数x,因为我们要用到它。(内置函数也有参数x,只不过说不需要定义,因为已经提前定义好了)

然后函数名字被用作是行4的局域框架标签,以及很重要的是调用时,函数调用所创设的局域环境变量值被赋给了函数的正式参数x,并返回4

这里要强调的是,老师认为函数的函数签名(signature)很重要,它包含了函数中创造局域框架环境时候所需要的所有信息:

(1)上头说的函数名字square成了局域框架的标签;(呃不是值赋值给参数,就是参数绑定到值这种说法挺让人犯嘀咕的,可能就跟sem的因子载荷赋值一样是反过来说的吧。)

(2)然后括号中的变量x则可以被赋予环境当中的变量值-2

函数签名(signature)告知了我们每当调用这个函数的时候,我们该如何建局域框架。

在环境中查找名 looking up names in environments

        本页PPT内容旨在对python语法中某个name出现重名情况下的name含义指代进行界定。因为同意name可以同时作为函数主体参数名、函数名,此时,name的含义可能产生混淆。

每一项表达都在环境当中被计算/估值?,

目前为止的环境要么是:

  • 单独宏框架;
  • 局部框架,跟着宏框架(?)

【重要】环境(小节2)=一序列框架;

图 ↑以上这个圈圈里的就叫做环境 

一个名,被估值给 在发现这一名的现有环境中最早框架赋值给那个名的值(???what)

eg 查找平方函数主体中的一些名(在函数调用的步骤2中执行此操作):

在局域框架当中查找;

然后如果找不到的话,在宏框架当中查找(内置名如“max”也在宏观框架当中,但我们不在环境图表中列出它)

- 【迷惑】……呃,等等等等……name是专指变量名的意思吗?

好问题,事实上这个小问题的回答也将伴随着对looking up names in environments含义理解的解决而解决,这是一个重要的基本术语厘清。

(看起来不是,因为函数的name也叫name,姑且叫name作名吧)?读这页PPT有点迷惘了。然后没百度到术语意思,但是意外检索到了术语对照表 — Python 3.12.5 文档中对annotate v. 注释等术语的解释(没收录name的含义)stata help大法好哇。

---单看理论没懂,举个例子↓

from operator import mul
mul(3, 4)
def square(square):
     return mul(square, square)
square
square(-2)

那么运行这一程序,这里的槽点在于函数名和函数中的参数名重复了,函数还是能跑的起来。

调用=查找】原理是当我调用函数的时候,我实际是在系统中查找这个函数(扣题),我把局域环境命名为square,于是再将变量值-2绑定给名square,即正式参数。

那么现在就说是,square在这个环境中的含义与之前有些不同。(?)

现在,它意味着-2。 因为首先在我局域环境中查找它,并且我找到它。所以实际上我没有在宏框架之中查找过square。

再看一遍原理:

A name evaluates to the value [bound to that name in the earliest frame of the current environment (in which that name is found)]. 一个名的计算结果为这样一个值,这个值绑定于当前环境下检索得到这个名的最早框架

  • “evaluates to”通常用于数学或编程语境中,表示计算某个表达式或函数的结果。

这里,name是指变量名/函数名均可(譬如上面的square,就既是函数名,又是参数名)

结论:本例当中square这个名实际上是意味着变量值argument-2,这是因为

~[辨析] 此前的案例里,square意味着函数名——因为在步骤2. 将变量值赋值给函数正式参数的过程当中,我们使用的参数名是x,随后第三步才在宏观环境中查找作为函数名的名square。

而在案例二当中,我们遵循函数调用步骤,首先在步骤2:局域框架赋值这一步look up了作为函数正式参数名的名square,因此square就意味着正式参数名,而不再对宏框架进行查找。

【总结】因为函数调用过程为:先检索函数主体中的参数名并赋值;再检索函数

em……其实对于这个知识点有些疑惑,就是函数调用过程如果不是先通过函数名找到宏观环境中的函数的话,又怎么准确调用其主体中的参数名呢?这个逻辑我是看不懂的,留一个问号在这里。


更新:

查了一些听课笔记和命名查找,我想命名查找规则函数调用可能是分开的……这里合起来讲反而混淆了。

Python3 命名空间和作用域 | 菜鸟教程 (runoob.com)

感觉这篇笔记在理论上比较好地说清出了命名查找规则。也就是说name looking up的规则是:

local→global

使用变量square时,Python 的查找顺序为:局部→全局→内置,从而对变量的含义进行界定。在不同层次命名空间的使用名冲突的时候,优先使用最微观命名。

这个过程和函数调用过程是独立的(……)老师借用calling过程可视化去进行讲解的话很容易引发一些歧义啊喂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值