python 函数0一起名(初识函数)

读书目录

干什么要用函数

函数的定义和调用

函数的重临值

函数的参数

小结

 

IPC是Inter-Process
Communication的缩写,直译为经过间通讯,说白了就是经过间发新闻。大家在上壹节中把这种新闻传递比作邮政系统,但实质上那种比喻并不全对。有的音讯机制是很像收发邮件的,那种称为异步IPC,意思是说,发信者发完就去干别的了,收信者也如出壹辙,看看信箱里没信,也不坐在旁边傻等。而有另壹种音讯机制正好相反,被喻为同步IPC,它不像邮寄,倒像接力赛,发送者平素等到接收者收到音信才肯放手,接收者也一致,接不到就径直等着,不干别的。
自然你能够把二头IPC也比作邮寄,只可是寄信的人从把信投到信箱里的那一刻早先,就住在邮局不走了,其余什么也不干了,就等着邮局说:“男士儿,你的信对方已经吸收接纳了,放心回家吧!”那才留恋地离开。收信的也同等,1旦决定收信,就守在自个儿信箱前边不走了,一贯等,连觉也不睡,望穿秋水,等信拿在手里了,那才回屋,每收贰次信,就得瘦个十几斤。
作者们都以脾性中人,大家挑选傻等,或曰同步IPC。
手拉手IPC有多少的益处,比如:
• 操作系统不须要此外维护缓冲区来存放正在传递的新闻;
• 操作系统不须要保留一份音讯副本;
• 操作系统不供给维护接收队列(发送队列照旧须要的);
• 发送者和接收者都可在任曾几何时刻清晰且易于地精晓新闻是还是不是送达;
• 从贯彻系统调用的角度来看,同步IPC特别客观──当使用系统调用时,大家实在要求拭目以俟内核重临结果之后再持续。
那么些特点读者或者无法一下子百分之百领略,不妨,我们接下去写完代码,你就全都理解了。
实现IPC
Minix的IPC机制大家曾经理解了,它的主导乃在于“int
SYSVEC”那个软中断以及与之对应的sys_call()那个函数。扩大3个种类调用对大家来讲已是信手拈来的事,根据表7.六一步一步来就好了。大家把这几个新的体系调用起名字为sendrec。sendrec和sys_sendrec的函数体分别见上边两段代码:
25 sendrec:
26         mov eax, _NR_sendrec
27         mov ebx, [esp + 4] ; function
28         mov ecx, [esp + 8] ; src_dest
29         mov edx, [esp + 12] ; p_msg
30         int INT_VECTOR_SYS_CALL
31         ret
53
/*****************************************************************************
54 * sys_sendrec
55
*****************************************************************************/
56 /**
57 * <Ring 0> The core routine of system call ‘sendrec()’.
58 *
59 * @param function SEND or RECEIVE
60 * @param src_dest To/From whom the message is transferred.
61 * @param m Ptr to the MESSAGE body.
62 * @param p The caller proc.
63 *
64 * @return Zero if success.
65
*****************************************************************************/
66 PUBLIC int sys_sendrec(int function, int src_dest, MESSAGE* m,
struct proc* p)
67 {
68         assert(k_reenter == 0); /* make sure we are not in ring0
*/
69         assert((src_dest >= 0 && src_dest < NR_TASKS +
NR_PROCS) ||
70         src_dest == ANY ||
71         src_dest == INTERRUPT);
72
73         int ret = 0;
74         int caller = proc2pid(p);
75         MESSAGE* mla = (MESSAGE*)va2la(caller, m);
76         mla->source = caller;
77
78         assert(mla->source != src_dest);
79
80         /**
81         * Actually we have the third message type: BOTH. However, it
is not
82         * allowed to be passed to the kernel directly. Kernel
doesn’t know
83         * it at all. It is transformed into a SEND followed by a
RECEIVE
84         * by ‘send_recv()’.
85         */
86         if (function == SEND) {
87                 ret = msg_send(p, src_dest, m);
88                 if (ret != 0)
89                 return ret;
90         }
91         else if (function == RECEIVE) {
92                 ret = msg_receive(p, src_dest, m);
93                 if (ret != 0)
94                 return ret;
95         }
96         else {
97                 panic(”{sys_sendrec}␣invalid␣function:␣”
98                 ”%d␣(SEND:%d,␣RECEIVE:%d).”, function, SEND,
RECEIVE);
99         }
100       
101         return 0;
102 }
表七.陆的末尾一步中涉及,假诺参数个数与原先的体系调用比有所扩张,则供给修改kernel.asm中的sys_call。额外要专注,大家新加的参数是透过edx这几个参数字传送递的,而save那么些函数中也应用了寄存器dx,所以我们同时须求修改save,见如下代码:

怎么要用函数

以后python届爆发了三个大事件,len方法突然不可能一贯用了。。。

接下来未来有二个要求,让您总计’hello world’的长短,你怎么计算?

这么些供给对于当今的您其实简单,咱们一并来写一下。

起名 1起名 2

s1 = "hello world"
length = 0
for i in s1:
    length = length+1

print(length)

for循环达成len功效

好了,功效达成了,卓殊完美。然后将来又有了五个急需,要总括别的一个字符串的尺寸,”hello
eva”.

于是乎,那年你的代码就改为了那样:

起名 3起名 4

起名 5

s1 = "hello world"
length = 0
for i in s1:
    length = length+1

print(length)

s2 = "hello eva"
length = 0
for i in s2:
    length = length+1

print(length)

起名 6

for循环完成len作用二

那样实在能够完成len方法的意义,可是总感觉不是那么完美?为何吧?

率先,此前如若大家履行len方法就能够直接得到二个字符串的尺寸了,现在为了贯彻平等的职能大家把相同的代码写了累累遍
—— 代码冗余

其次,此前我们只写两句话读起来也很简短,一看就了解那两句代码是在测算长度,可是刚刚的代码却不那么简单读懂
—— 可读性差

print(len(s1))
print(len(s2))

大家就想啊,借使大家能像使用len一样采纳大家这一大段“总计长度”的代码就好了。那种感觉有点像给那段代码起了1个名字,等大家用到的时候一贯喊名字就能履行那段代码似的。假诺能如此,是还是不是很周详啊?

回去顶部

   311 ;

   312 ; save

初识函数定义与调用

当今就教大家二个既能,让你们把代码装起来。

起名 7起名 8

def mylen():
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)

View Code

咱俩1块来分析一下那段代码做了什么。

实际不外乎def那1行和前面包车型大巴缩进,其余的切近就是健康的推行代码。大家来推行一下,哦,好像啥也没产生。

碰巧我们早已说过,那是把代码装起来的经过。你以后只会往里装,还不会往出拿。那么应该怎么往出拿呢?小编来报告大家:

mylen()

是还是不是很粗略?是或不是似曾相识?这正是代码取出来的长河。刚刚大家就写了二个函数,并且成功调用了它。

起名 9起名 10

起名 11

#函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)

#函数调用  
mylen()

起名 12

函数的定义和调用

总结一:

定义:def
关键词开头,空格之后接函数名号和圆括号(),最后还有二个”:”。

   def
是原则性的,不能够变,必须是连接的def八个字母,不能够分开。。。它们要接近相爱的在壹块。

   空格
为了将def关键字和函数名分别,必须空(4声),当然你能够空二格、三格仍旧您想空多少都行,但平日人依然空一格。

   函数名:函数名只好分包字符串、下划线和数字且无法以数字开端。尽管函数名能够任由起,但大家给函数起名字或然要尽量不难,并能表明函数功效

   括号:是必须加的,先别问为什么要有括号,不问可见足够括号就对了!

注释:每1个函数都应有对职能和参数进行相应的求证,应该写在函数上边第一行。以抓好代码的可读性。

调用:就是 函数名() 要记得加上括号,好么好么好么。

重回顶部

   313 ;

   314 save:
   315         pushad ; ‘.
   316         push ds ; |
   3一七         push es ; | 保存原寄存器值
   318         push fs ; |
   319         push gs ; /
   320
   3二1         ;; 注意,从那边开头,一贯到‘mov esp,
StackTop’,中间坚决不可能用push/pop 指令,
   32二         ;; 因为如今esp 指向proc_table 里的某些地点,push
会破坏掉进度表,导致灾祸性后果!
   323
=> 3二四         mov esi, edx ; 保存edx,因为edx
里保存了系统调用的参数
   3二五         ;(没用栈,而是用了另二个寄存器esi)
   326         mov dx, ss
   327         mov ds, dx
   328         mov es, dx
   329         mov fs, dx
   330
=> 331         mov edx, esi ; 恢复edx
   332
   33三         mov esi, esp                         ;esi =
进度表初步地址
   334
   335         inc dword [k_reenter]                ;k_reenter++;
   336         cmp dword [k_reenter], 0             ;if(k_reenter
==0)
   337         jne .1                               ;{
   338         mov esp, StackTop                    ; mov esp, StackTop
<–切换来内核栈
   339         push restart                         ; push restart
   340         jmp [esi + RETADR – P_STACKBASE]     ; return;
   3肆一 .壹:                                          ;} else {
已经在内核栈,不须求再切换
   342         push restart_reenter                 ; push
restart_reenter
   343         jmp [esi + RETADR – P_STACKBASE]     ; return;
   344                                              ;}
   345
   346

函数的重回值

刚巧大家就写了四个函数,那么些函数能够协助大家计算字符串的尺寸,并且把结果打字与印刷出来。不过,那和我们的len方法还不是太1样。哪儿不均等啊?从前作者们调用len方法会获得三个值,大家必须用三个变量来收纳这几个值。

str_len = len('hello,world')

这个str_len正是‘hello,world’的尺寸。那咱们协调写的函数能不负众望那一点么?大家也来试一下。

起名 13起名 14

起名 15

#函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)

#函数调用
str_len = mylen()
print('str_len : %s'%str_len)

起名 16

函数调用的结果

很不满,如若你执行那段代码,获得的str_len
值为None,那表达我们那段代码什么也并未有给你回到。

那什么让它也想len函数1样再次来到值呢?

起名 17起名 18

起名 19

#函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    return length

#函数调用
str_len = mylen()
print('str_len : %s'%str_len)

起名 20

View Code

大家只要求在函数的最终加上二个return,return后边写上您要回来的值就能够了。

接下去,大家就来商量一下以此return的用法。

return关键字的作用

  return
是一个要害字,在pycharm里,你会看到它变成高粱红了。你不可能不一字不差的把那几个单词给背下来。

  那个词翻译过来就是“重临”,所以我们管写在return前边的值叫“再次来到值”

要钻探重返值,大家还要理解重回值有二种景况:分别是未有重返值、重返2个值、重回多少个值

尚无重临值

  不写return的状态下,会默许重返一个None:我们写的率先个函数,就不曾写return,那就是绝非再次回到值的壹种状态。 

起名 21起名 22

起名 23

#函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)

#函数调用
str_len = mylen()
#因为没有返回值,此时的str_len为None
print('str_len : %s'%str_len)

起名 24

不写return  

  只写return,前面不写别的剧情,也会回来None,有的同学会奇怪,既然未有要回到的值,完全能够不写return,为什么还要写个return呢?那里大家要说一下return的其余用法,就是1旦遇上return,甘休全部函数。  

起名 25起名 26

起名 27

def ret_demo():
    print(111)
    return
    print(222)

ret = ret_demo()
print(ret)

起名 28

只写return

      return None:和下面的二种处境1模一样,大家一般不这么写。

起名 29起名 30

起名 31

def ret_demo():
    print(111)
    return None
    print(222)

ret = ret_demo()
print(ret)

起名 32

return None

重返一个值

     
刚刚我们已经写过二个赶回2个值的情况,只需在return前面写上要回到的内容即可。  

起名 33起名 34

起名 35

#函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    return length

#函数调用
str_len = mylen()
print('str_len : %s'%str_len)

起名 36

回来一个值

  在意:return和重回值之间要有空格,能够回去任意数据类型的值

归来八个值

  能够回去任意多个、任意数据类型的值

起名 37起名 38

起名 39

def ret_demo1():
    '''返回多个值''' 
    return 1,2,3,4


def ret_demo2():
    '''返回多个任意类型的值'''
    return 1,['a','b'],3,4

ret1 = ret_demo1()
print(ret1)
ret2 = ret_demo2()
print(ret2)

起名 40

再次来到八个值

  重临的七个值会被集体成元组被再次来到,也足以用两个值来收纳

起名 41起名 42

起名 43

def ret_demo2():
    return 1,['a','b'],3,4

#返回多个值,用一个变量接收
ret2 = ret_demo2()
print(ret2)

#返回多个值,用多个变量接收
a,b,c,d = ret_demo2()
print(a,b,c,d)

#用多个值接收返回值:返回几个值,就用几个变量接收
a,b,c,d = ret_demo2()
print(a,b,c,d)

起名 44

多个再次回到值的吸收

 

  原因:  

>>> 1,2  #python中把用逗号分割的多个值就认为是一个元组。
(1, 2)
>>> 1,2,3,4
(1, 2, 3, 4)
>>> (1,2,3,4)
(1, 2, 3, 4)

起名 45起名 46

起名 47

#序列解压一
>>> a,b,c,d = (1,2,3,4)
>>> a
1
>>> b
2
>>> c
3
>>> d
4
#序列解压二
>>> a,_,_,d=(1,2,3,4)
>>> a
1
>>> d
4
>>> a,*_=(1,2,3,4)
>>> *_,d=(1,2,3,4)
>>> a
1
>>> d
4
#也适用于字符串、列表、字典、集合
>>> a,b = {'name':'eva','age':18} 
>>> a
'name'
>>> b
'age'

起名 48

队列解压扩充

 

回到顶部

   347 ;

   348 ; sys_call

函数的参数 

现行反革命,大家已经把函数重临值相关的工作商量清楚了,大家友好早已到位了一个足以回去字符串长度的函数。可是今后以此函数照旧不到家,此前我们使用len函数的时候得是length
= len(“hello
world”),那样作者得以想总括何人就总结何人的尺寸。可是今后我们写的这几个函数,只可以总括多少个“hello
world”的长度,换三个字符串好像正是12分了。那可如何是好?

起名 49起名 50

起名 51

#函数定义
def mylen(s1):
    """计算s1的长度"""
    length = 0
    for i in s1:
        length = length+1
    return length

#函数调用
str_len = mylen("hello world")
print('str_len : %s'%str_len)

起名 52

带参数的函数

大家告知mylen函数要计算的字符串是哪个人,那几个历程就叫做
传递参数,简称传参,咱俩调用函数时传递的这几个“hello
world”和定义函数时的s一就是参数

实参与形参

参数还有个别:

我们调用函数时传递的这一个“hello
world”被誉为实际参数,因为这几个是实际上的要付出函数的始末,简称实参。

概念函数时的s一,只是四个变量的名字,被称之为花样参数,因为在概念函数的时候它只是3个试样,表示那里有三个参数,简称形参。  

传递几个参数

参数能够传递多个,三个参数之间用逗号分割。

起名 53起名 54

def mymax(x,y):
    the_max = x if x > y else y
    return the_max

ma = mymax(10,20)
print(ma)

传送四个参数

也多亏因为须要传递两个参数、可以传递四个参数,才会有了后面那一多级参数相关的传说。。。

职位参数

  站在实参角度

    一.如约岗位传值

起名 55起名 56

起名 57

def mymax(x,y):
    #此时x=10,y=20
    the_max = x if x > y else y
    return the_max

ma = mymax(10,20)
print(ma)

起名 58

听从岗位传参

    贰.遵照重点字传值

起名 59起名 60

起名 61

def mymax(x,y):
    #此时x = 20,y = 10
    print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(y = 10,x = 20)
print(ma)

起名 62

依照重点字传参

    三.岗位、关键字方式混着用

起名 63起名 64

起名 65

def mymax(x,y):
    #此时x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(10,y = 20)
print(ma)

起名 66

职位、关键字混用传参

      正确用法

      难点壹:地方参数必须在重中之重字参数的如今

      难题二:对于贰个形参只好赋值1回      

  站在形参角度

    地方参数必须传值

起名 67起名 68

起名 69

def mymax(x,y):
    #此时x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

#调用mymax不传递参数
ma = mymax()
print(ma)

#结果
TypeError: mymax() missing 2 required positional arguments: 'x' and 'y'

起名 70

地方参数必须传参

暗许参数

    一.好端端使用

      使用方法

      为啥要有暗中认可参数:将转变比较小的值设置成暗中认可参数

    二.暗中认可参数的定义

起名 71起名 72

起名 73

def stu_info(name,sex = "male"):
    """打印学生信息函数,由于班中大部分学生都是男生,
        所以设置默认参数sex的默认值为'male'
    """
    print(name,sex)


stu_info('alex')
stu_info('eva','female')

起名 74

私下认可参数

    三.参数陷阱:暗许参数是一个可变数据类型

起名 75起名 76

def defult_param(a,l = []):
    l.append(a)
    print(l)

defult_param('alex')
defult_param('egon')

参数陷阱

 

动态参数

  按职分传值多余的参数都由args统壹接受,保存成一个元组的款型

起名 77起名 78

起名 79

def mysum(*args):
    the_sum = 0
    for i in args:
        the_sum+=i
    return the_sum

the_sum = mysum(1,2,3,4)
print(the_sum)

起名 80

*args求和函数应用

起名 81起名 82

def stu_info(**kwargs):
    print(kwargs)
    print(kwargs['name'],kwargs['sex'])

stu_info(name = 'alex',sex = 'male')

**kwargs应用  

  实际付出中:

  今后还会用到的情景。。。

  问题:

    地方参数、暗中认可参数、动态参数定义的相继以及收受的结果?

重返顶部

   349 ;

   350 sys_call:
   351         call save
   352
   353         sti
   354         push esi
   355
   356         push dword [p_proc_ready]
=> 357         push edx
   358         push ecx
   359         push ebx
   360         call [sys_call_table + eax * 4]
=> 361         add esp, 4 * 4
   362
   363         pop esi
   364         mov [esi + EAXREG – P_STACKBASE], eax
   365         cli
   366
   367         ret
sys_sendrec()那一个函数被规划得格外简单,它可以描述为:把SEND音信交给msg_send()处理,把RECEIVE音讯交给msg_receive()处理。
msg_send()和msg_receive()这三个函数大家过会儿细细分解,先来看看在此以前没出现过的assert()和panic()。那多个函数固然起的是扶持作用,但相对不是开玩笑,因为在大家接下去要处理的消息收发中,有一对编制程序细节还真不难令人迷糊,那时候assert()就大显神威了,它会在错误被推广在此以前文告你。panic()的功效也近乎,用于布告你发出了惨重的荒谬。

本章小结

面向进程编制程序的题材:代码冗余、可读性差、可扩充性差(不易修改)

概念函数的平整:

起名 83

1.定义:def 关键词开头,空格之后接函数名称和圆括号()。
2.参数:圆括号用来接收参数。若传入多个参数,参数之间用逗号分割。
    参数可以定义多个,也可以不定义。
    参数有很多种,如果涉及到多种参数的定义,应始终遵循位置参数、*args、默认参数、**kwargs顺序定义。
    如上述定义过程中某参数类型缺省,其他参数依旧遵循上述排序
3.注释:函数的第一行语句应该添加注释。
4.函数体:函数内容以冒号起始,并且缩进。
5.返回值:return [表达式] 结束函数。不带表达式的return相当于返回 None

def 函数名(参数1,参数2,*args,默认参数,**kwargs):
        """注释:函数功能和参数说明"""
        函数体
        ……
        return 返回值

起名 84

调用函数的条条框框:

起名 85

1.函数名()
    函数名后面+圆括号就是函数的调用。
2.参数:
    圆括号用来接收参数。
    若传入多个参数:
        应按先位置传值,再按关键字传值
        具体的传入顺序应按照函数定义的参数情况而定
3.返回值
    如果函数有返回值,还应该定义“变量”接收返回值
    如果返回值有多个,也可以用多个变量来接收,变量数应和返回值数目一致

无返回值的情况:
函数名()

有返回值的情况:
变量 = 函数名()

多个变量接收多返回值:
变量1,变量2,... = 函数名()

起名 86

参数总计:

起名 87

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图