Python之初识函数

1、什么是函数?

函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可

2、为什么使用函数?

函数能提高应用的模块性,和代码的重复利用率。

你已经知道Python提供了许多内建函数,比如print()。

但你也可以自己创建函数,这被叫做用户自定义函数。

3、函数的特性

1)代码重用

2)保持一致性

3)可扩展性

4、函数的创建

定义函数使用 def 关键字,一般格式如下:
# def 函数名(参数列表):
#    函数体


def hello():
    '''我是描述信息:描述该函数是干什么用的'''
    print('hello')


hello()  # 调用
print(hello.__doc__)   # 通过 hello.__doc__ 查看描述

'''
hello
描述信息,描述该函数是干什么用的
'''

优雅取代多分支 if

def foo():
    print('foo')

def bar():
    print('bar')

dic={
    'foo':foo,
    'bar':bar,
}
while True:
    choice=input('>>: ').strip()
    if choice in dic:
        dic[choice]()

 

5、函数名的命名规则

a、函数名必须以下划线或字母开头,可以包含任意字母、数字或下划线的组合。不能使用任何的标点符号;

b、函数名是区分大小写的。

c、函数名不能是保留字。


6、函数的调用

# 语句形式: foo() 或 m=foo() 会执行函数 foo,并输出屏幕
def foo():
    print('foo')

foo()
m = foo()
'''
foo
foo
'''

# 表达式形式:res=10*my_sum(1,2),先执行函数,如果有 print 就输出屏幕,并把函数结果*10赋值给 res
def my_sum(a, b):
    print('test')
    return a+b

res = 10*my_sum(1, 2)
print(res)
'''
test
30
test
'''

# 函数调用作为另外一个函数的参数:print(my_sum(1,2))
print(my_sum(1, 2))   # 3


7、函数的参数

a、形参和实参

形参:形式参数,不是实际存在,是虚拟变量。在定义函数和函数体的时候使用形参,目的是在函数调用时接收实参(实参个数,类型应与实参一一对应)

实参:实际参数,调用函数时传给函数的参数,可以是常量,变量,表达式,函数,传给形参

区别:形参是虚拟的,不占用内存空间,形参变量只有在被调用时才分配内存单元,实参是一个变量,占用内存空间,数据传送单向,实参传给形参,不能形参传给实参

理解:实参本质是形参变量名的值,形参本质是变量名

注意:实参不要传递可变的数据类型,因为在函数里,函数可以对实参进行修改,从而影响全局变量

例1:
def f(x):     #形参
    print(x)

f(3)    # 实参


例2:
import time
times=time.strftime('%Y--%m--%d')

def f(times):
    print('Now  time is : %s'%times)
f(times)


例3:
def show_shopping_car():
    saving = 1000000
    shopping_car = [
        ('Mac', 9000),
        ('kindle', 800),
        ('tesla', 100000),
        ('Python book', 105),
    ]
    print('您已经购买的商品如下'.center(50, '*'))
    for i, v in enumerate(shopping_car, 1):
        print('%s:  %s' % (i, v))

    expense = 0
    for i in shopping_car:
        expense += i[1]
    print('\n您的余额为 %s' % (saving-expense))

show_shopping_car()
'''
********************您已经购买的商品如下********************
1:  ('Mac', 9000)
2:  ('kindle', 800)
3:  ('tesla', 100000)
4:  ('Python book', 105)

您的余额为 890095
'''
1:形参和实参例子
def action1(n):
    print('starting action1...')

    with open('日志记录', 'a') as f:
        f.write('end action%s\n' % n)


def action2(n):
    print('starting action2...')

    with open('日志记录', 'a') as f:
        f.write('end action%s\n' % n)


def action3(n):
    print('starting action3...')

    with open('日志记录', 'a') as f:
        f.write('end action%s\n' % n)


action1(1)
action2(2)
action3(3)
'''
starting action1...
starting action2...
starting action3...

打开文件查看
end action1
end action2
end action3
'''


# ***************代码重用
# 上面发现每个函数都有打开文件,写内容的重复代码,把这些代码提取出来
def logger(n):
    with open('日志记录', 'a') as f:
        f.write('end action%s\n' % n)


def action1():
    print('starting action1...')
    logger(1)


def action2():
    print('starting action2...')
    logger(2)


def action3():
    print('starting action3...')
    logger(3)


action1()
action2()
action3()
'''
starting action1...
starting action2...
starting action3...

打开文件查看
end action1
end action2
end action3
'''

# ***************可扩展和保持一致
# 再不改变各个 action 函数内部的前提下额外为日志加上时间
import time

def logger(n):
    time_format = '%Y-%m-%d %X'
    time_current = time.strftime(time_format)

    with open('日志记录', 'a') as f:
        f.write('%s end action%s\n' % (time_current, n))


def action1():
    print('starting action1...')
    logger(1)


def action2():
    print('starting action2...')
    logger(2)


def action3():
    print('starting action3...')
    logger(3)


action1()
action2()
action3()

'''
starting action1...
starting action2...
starting action3...

打开文件查看
2018-05-02 12:03:39 end action1
2018-05-02 12:03:39 end action2
2018-05-02 12:03:39 end action3
'''
2:一个例子来说明函数的三个特性


b、位置参数(必备参数)

位置参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

def f(name, age):
    print('I am %s,I am %d' % (name, age))

f('alex', 18)
f('alvin', 16)   # 位置参数,按函数提供的顺序,传递参数

'''
I am alex,I am 18
I am alvin,I am 16
'''


c、关键字参数(实参参数)

关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

def f(name, age):
    print('I am %s,I am %d' % (name, age))

# f(16, 'alvin')  # 报错:TypeError: %d format: a number is required, not str
f(age=16, name='alvin')  # 关键字参数,指定 age 和 name 的值

'''
I am alvin,I am 16
'''


d、缺省参数(默认参数)

调用函数时,缺省参数的值如果没有传入,则被认为是默认值。下例如果sex没有被传入,会打印默认的sex。

默认参数一定要放在位置参数后面

def print_info(name, age, sex='male'):    # 性别的默认值为 male,下面传递的时候可以改
    print('Name:%s' % name)
    print('age:%s' % age)
    print('Sex:%s' % sex)

print_info('hjc', 24, 'fmale')     # 上面定义的 male ,这里传递参数可以改
print_info('hjc', 24)  # 没有传递 sex 的参数,默认会显示 sex 的默认值
'''
Name:hjc
age:24
Sex:fmale

Name:hjc
age:24
Sex:male
'''


e、不定长参数

你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。

*args
def add(*args): # args 内部是一个元祖
    sum = 0
    for v in args:
        sum += v
    return sum

print(add(1, 4, 6, 9))   # 20
print(add(1, 4, 6, 9, 5))  # 25

加了星号*)的变量名会存放所有未命名的变量参数(值)。而加(**)的变量名会存放命名的变量参数(键值)

**kwargs
def print_info(**kwargs):  # kwargs 内部是一个字典
    for i in kwargs:
        print('%s:%s' % (i, kwargs[i]))  # 根据参数可以打印任意相关信息了
    return

print_info(name='alex', age=18, sex='female', hobby='girl',nationality='Chinese', ability='Python')
'''
name:alex
age:18
sex:female
hobby:girl
nationality:Chinese
ability:Python
'''

不定长参数位置说明

关于不定长参数的位置:*args 放在左边,**kwargs 参数放在右边

def info(*args, **kwargs):  # 位置固定死了,反过来会报错
    print('args:', args)
    print('kwargs:', kwargs)
    for i in kwargs:
        print('%s:%s' % (i, kwargs[i]))


info('hjc', 24, 'male', job='IT', hobby='girls', height=100)
'''
args: ('hjc', 24, 'male')
kwargs: {'job': 'IT', 'hobby': 'girls', 'height': 100}
job:IT
hobby:girls
height:100
'''


# def print_info(name,**kwargs,*args):报错
def print_info(name, *args, **kwargs):
    print('Name:%s' % name)
    print('args:', args)
    print('kwargs:', kwargs)


print_info('alex', 18, hobby='girl', nationality='Chinese', ability='Python')
'''
Name:alex
args: (18,)
kwargs: {'hobby': 'girl', 'nationality': 'Chinese', 'ability': 'Python'}
'''

# print_info(hobby='girl', 'alex', 18, nationality='Chinese', ability='Python')  # 报错
# print_info('alex', hobby='girl', 18, nationality='Chinese', ability='Python')  # 报错

注意,还可以这样传参:

*args 相当于位置参数

**kwargs 相当于关键字参数

*args
def f(*args):
    print(args)

f(*[1, 2, 5]) # 传递一个列表,(1, 2, 5)
f(*(1, 2, 5)) # 传递一个元组(1, 2, 5)

**kwargs
方式1:
def f(**kargs):
    print(kargs)

f(**{'name': 'alex'})  # {'name': 'alex'}

方式2:
def f2(**kwargs):
    print(kwargs)

f2(info={'name': 'alex'})  # {'info': {'name': 'alex'}}


8、高阶函数

高阶函数是至少满足下列一个条件的函数:

1、接受一个或多个函数作为输入,也就是把函数名作为参数输入

2、函数名可以作为返回值

例1:
def add(x, y, f):
    return f(x) + f(y)

res = add(3, -6, abs)  # abs 函数作为参数传递
print(res)


例2:
def foo():
    x = 3
    def bar():
        return x
    return bar  # 返回函数名:一个内存地址,也是函数的本质

print(foo)
print(foo())


例3:
def f(n):
    return n*n

def foo4(a, b, func):
    ret = func(a)+func(b)
    return ret

print(foo4(1, 2, f))
'''
解释:
先定义一个函数 f,函数 f 的对象是 n*n
定义 foo4 函数,形参是(a,b,func)
print(foo4(1,2,f))
这里的 f,作为 foo4 的形参,func 调用函数 f,f(a)=f(1*1)=1,f(b)=f(2*2)=4
ret=1+4
'''


9、函数返回值

要想获取函数的执行结果,就可以用return语句把结果返回

注意:

  1. 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
  2. 如果未在函数中指定return,那这个函数的返回值为None
  3. return 多个对象,解释器会把这多个对象组装成一个元组作为一个整体结果输出。可以通过变量压缩去取元组中的值
  4. 通常无参函数不需要给 return 返回值
  5. return 只有一个对象,返回的就是这个对象
  6. 变量压缩:tuple=(1,2,3)————a,b,c=(1,2,3)
def f():
    print('ok')
    return True # 作用:1:结束函数;2:返回某个对象

f()

def foo():
    return 1,'alex',8 

print(foo()) # (1, 'alex', 8),多个对象组装成一个元组,可以用多个变量去接收

.

posted @ 2018-05-04 17:14  H-JIACHENG  阅读(286)  评论(0编辑  收藏  举报