百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

Python函数定义及参数详解(python的函数定义规范)

off999 2024-10-18 07:59 60 浏览 0 评论

函数定义

首先我们来创建一个函数,输出指定范围内的斐波拉契数列(Fibonacci series)。

私信小编01即可获取Python学习资料

#!/usr/bin/env python 
#coding=utf-8
'''
Created on 2016年9月4日下午2:37:31
@author: Flowsnow
@file: D:/Workspaces/eclipse/HelloPython/main/FibonacciSeries.py
@function: 定义函数-输出给定范围内的斐波拉契数列
'''
def Fibonacci(n):
    #print "success"
    a=0
    b=1
    while a<n:
        print a,
        a,b=b,a+b

#call the function Fibonacci
Fibonacci(2000)
print '\n',
print Fibonacci
f=Fibonacci
f(100)
print '\n',
print Fibonacci(0)

<!--more-->

输出结果如下:

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 
<function Fibonacci at 0x000000000258D9E8>
0 1 1 2 3 5 8 13 21 34 55 89 
None

由第一行可知 Fibonacci函数输出了2000以内的斐波拉契数列。

由第二行可知 Fibonacci函数在内存中的地址

由第三行可知 将Fibonacci函数的地址值赋给另外一个变量f之后,f也就是一个函数了,这类似于重名机制

由第四行可知 虽然Fibonacci函数没有 return 语句,但是如果我们使用 print 输出的时候可以发现还是有返回值的,只是这个返回值是 None ,这是Python的內建名称。

我们也可以写一个函数,不输出斐波拉契数列的值,而是把值作为返回值返回。

#!/usr/bin/env python 
#coding=utf-8
'''
Created on 2016年9月4日下午3:07:06
@author: Flowsnow
@file: D:/Workspaces/eclipse/HelloPython/main/FibonacciSeriesAdv.py
@function: 函数定义-返回斐波拉契数列,而不是直接打印
'''
def Fibonacci(n):
    a=0
    b=1
    result=[]
    while a<n:
        result.append(a)
        a,b=b,a+b
    return result
result=Fibonacci(2000)
for x in result:
    print x,

输出结果:0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

参数详解

Python 的内建标准类型有一种分类标准是分为可变类型与不可变类型

  • 可变类型:列表、字典
  • 不可变类型:数字、字符串、元组

上面函数定义中的参数都是属于不可变类型的。

可变参数三种情况:默认参数,位置参数 *args 关键字参数 **kwargs 。

默认参数

默认参数的好处就是在调用函数的时候写上去的参数比在函数定义时的参数少。例如:

#!/usr/bin/env python 
#coding=utf-8
'''
Created on 2016年9月5日下午2:50:12
@author: Flowsnow
@file: D:/Workspaces/eclipse/HelloPython/main/askYesOrNo.py
@function: 测试默认参数的使用
'''
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
    while True:
        ok = raw_input(prompt)
        if ok in ('y', 'ye', 'yes'):
            return True
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
        retries = retries - 1
        if retries < 0:
            raise IOError('refusenik user')
        print complaint

这个函数的调用方法有很多,比如:

ask_ok('OK to overwrite the file?')
ask_ok('OK to overwrite the file?', 2)
ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')

关于默认值,应该注意的是默认值只会在函数定义的时候被python解析一次。因此

i = 5

def f(arg=i):
    print arg

i = 6
f()

这段代码输出的应该是5,而不是6,就是因为i是在函数定义的时候解析的,这个时候i=5。

重要警告:默认值只会解析一次。当默认参数是可变对象时,影响比较大,比如列表,字典或者类的对象。下面演示的这个函数会把参数积累并传到随后的函数调用里面:

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

这段代码会输出

[1]
[2]
[3]

位置参数*args

位置参数需要在参数前面加一个星号。把参数收集到一个元tuple中,作为变量args。至于为什么叫位置参数,这个是因为各个参数是按照顺序接收的。

def argTest(arg1,*args):
    print arg1
    print('~start to print *args~')
    for x in args:
        print x,

argTest(1,'two',3)

这段代码会输出

1
~start to print *args~
two 3

args被解释为包含多个变量的元组tuple。因此也可用如下写法:

def argTest(arg1,*args):
    print arg1
    print('~start to print *args~')
    for x in args:
        print x,

#argTest(1,'two',3)
args=['two',3]
argTest(1,*args)

关键字参数**kwargs

函数也能够按照 kwarg=value 这种形式的关键字参数来调用。关键字参数需要在参数前面加两个星号。其作用是把参数收集成一个字典类型,包含参数名和值。

def argTest(arg1,**kwargs):
    print 'arg1',arg1
    for key in kwargs:
        print key,kwargs[key]
argTest(1,arg2='aa',arg3='bb')
argTest(arg1=1,arg2='aa',arg3='bb',arg4='cc')
arg={'arg2':'bb','arg3':'cc','arg4':'dd'}
argTest(arg1='ss',**arg)
argTest(arg1='ss',**arg)

这段代码会输出

arg1 1
arg2 aa
arg3 bb
arg1 1
arg2 aa
arg3 bb
arg4 cc
arg1 ss
arg2 bb
arg3 cc
arg4 dd
arg1 ss
arg2 bb
arg3 cc
arg4 dd

相关推荐

Linux 网络协议栈_linux网络协议栈

前言;更多学习资料(包含视频、技术学习路线图谱、文档等)后台私信《资料》免费领取技术点包含了C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,Z...

揭秘 BPF map 前生今世_bpfdm

1.前言众所周知,map可用于内核BPF程序和用户应用程序之间实现双向的数据交换,为BPF技术中的重要基础数据结构。在BPF程序中可以通过声明structbpf_map_def...

教你简单 提取fmpeg 视频,音频,字幕 方法

ffmpeg提取视频,音频,字幕方法(HowtoExtractVideo,Audio,SubtitlefromOriginalVideo?)1.提取视频(ExtractVi...

Linux内核原理到代码详解《内核视频教程》

Linux内核原理-进程入门进程进程不仅仅是一段可执行程序的代码,通常进程还包括其他资源,比如打开的文件,挂起的信号,内核内部的数据结构,处理器状态,内存地址空间,或多个执行线程,存放全局变量的数据段...

Linux C Socket UDP编程详解及实例分享

1、UDP网络编程主要流程UDP协议的程序设计框架,客户端和服务器之间的差别在于服务器必须使用bind()函数来绑定侦听的本地UDP端口,而客户端则可以不进行绑定,直接发送到服务器地址的某个端口地址。...

libevent源码分析之bufferevent使用详解

libevent的bufferevent在event的基础上自己维护了一个buffer,这样的话,就不需要再自己管理一个buffer了。先看看structbufferevent这个结构体struct...

一次解决Linux内核内存泄漏实战全过程

什么是内存泄漏:程序向系统申请内存,使用完不需要之后,不释放内存还给系统回收,造成申请的内存被浪费.发现系统中内存使用量随着时间的流逝,消耗的越来越多,例如下图所示:接下来的排查思路是:1.监控系统中...

彻底搞清楚内存泄漏的原因,如何避免内存泄漏,如何定位内存泄漏

作为C/C++开发人员,内存泄漏是最容易遇到的问题之一,这是由C/C++语言的特性引起的。C/C++语言与其他语言不同,需要开发者去申请和释放内存,即需要开发者去管理内存,如果内存使用不当,就容易造成...

linux网络编程常见API详解_linux网络编程视频教程

Linux网络编程API函数初步剖析今天我们来分析一下前几篇博文中提到的网络编程中几个核心的API,探究一下当我们调用每个API时,内核中具体做了哪些准备和初始化工作。1、socket(family...

Linux下C++访问web—使用libcurl库调用http接口发送解析json数据

一、背景这两天由于一些原因研究了研究如何在客户端C++代码中调用web服务端接口,需要访问url,并传入json数据,拿到返回值,并解析。 现在的情形是远程服务端的接口参数和返回类型都是json的字符...

平衡感知调节:“系统如人” 视角下的架构设计与业务稳定之道

在今天这个到处都是数字化的时代,系统可不是一堆冷冰冰的代码。它就像一个活生生的“数字人”,没了它,业务根本转不起来。总说“技术要为业务服务”,但实际操作起来问题不少:系统怎么才能快速响应业务需求?...

谈谈分布式文件系统下的本地缓存_什么是分布式文件存储

在分布式文件系统中,为了提高系统的性能,常常会引入不同类型的缓存存储系统(算法优化所带来的的效果可能远远不如缓存带来的优化效果)。在软件中缓存存储系统一般可分为了两类:一、分布式缓存,例如:Memca...

进程间通信之信号量semaphore--linux内核剖析

什么是信号量信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有。信号量的值为正的时候,说明它空闲。所测试的线程可以锁定而使用它。若为0,说明它被占用,测试的线程要进入睡眠...

Qt编写推流程序/支持webrtc265/从此不用再转码/打开新世界的大门

一、前言在推流领域,尤其是监控行业,现在主流设备基本上都是265格式的视频流,想要在网页上直接显示监控流,之前的方案是,要么转成hls,要么魔改支持265格式的flv,要么265转成264,如果要追求...

30 分钟搞定 SpringBoot 视频推拉流!实战避坑指南

30分钟搞定SpringBoot视频推拉流!实战避坑指南在音视频开发领域,SpringBoot凭借其快速开发特性,成为很多开发者实现视频推拉流功能的首选框架。但实际开发中,从环境搭建到流处理优...

取消回复欢迎 发表评论: