偷学Python第七天:函数和模块的使用

人生苦短我用Python

偷学Python第七天:函数和模块的使用

目标:可以用Python做一些简单的数据分析。
在这里插入图片描述

坚持完成自己的目标!勿忘初心~

今日学习目标

  • 函数的作用 - 代码的坏味道 / 用函数封装功能模块
  • 定义函数 - def语句 / 函数名 / 参数列表 / return语句 / 调用自定义函数
  • 调用函数 - Python内置函数 / 导入模块和函数
  • 函数的参数 - 默认参数 / 可变参数 / 关键字参数 / 命名关键字参数
  • 函数的返回值 - 没有返回值 / 返回单个值 / 返回多个值
  • 作用域问题 - 局部作用域 / 嵌套作用域 / 全局作用域 / 内置作用域 / 和作用域相关的关键字
  • 用模块管理函数 - 模块的概念 / 用自定义模块管理函数 / 命名冲突的时候会怎样(同一个模块和不同的模块)

学习内容

函数的作用

编程大师Martin Fowler先生曾经说过:“代码有很多种坏味道,重复是最坏的一种!”。

可以将重复的功能封装到一个称之为“函数”的功能模块中,用来实现单一,或相关联功能的代码段。

定义函数

规则:

函数代码块以 def 关键词开头,后接函数名和圆括号 ()

函数名命名规则跟变量的命名规则是一致

return关键字用于退出函数,选择性地向调用方返回一个表达式。

语法:

def 函数名(参数列表):
    函数体
    return语句
##定义一个函数 往里面穿两个参数
def sum( arg1, arg2 ):
   # 返回2个参数的和."
   total = arg1 + arg2
   print ("函数内 : ", total)
   return total
 
# 调用sum函数
a = sum( 10, 20 )
print ("函数外 : ", a)

b = sum( 20, 30 )
print ("函数外 : ", b)

函数的参数

参数的默认值

调用函数时,如果没有传递参数,则会使用默认参数。

def a( name, age = 12 ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用a函数
a( age=10, name="小红" )
print ("------------------------")
a( name="小明" )

可变参数

所谓可变参数指的是在调用函数时,可以向函数传入0个或任意多个参数。

往函数中以列表和元组的形式传参数时,使用*args

传入字典的值作为关键词参数时,使用**kwargs

示例代码:*args

# 用星号表达式来表示args可以接收0个或任意多个参数
def print_info(*args):
    # 可变参数可以放在for循环中取出每个参数的值
    print(args)
    for i in args:
        print(i)  # 遍历结果
    return


print_info("我最可爱")  # ('我最可爱',)
print_info(1, 2, 3, 4, 5, 6, 7)  # (1, 2, 3, 4, 5, 6, 7)
print_info("hello", "hi")  # ('hello', 'hi')

示例代码:*kwargs

def print_Info(**kwargs):
    print(kwargs)


print_Info(姓名="甜甜", 性别="女")  # {'姓名': '甜甜', '性别': '女'}

用模块管理函数

在同一个.py文件中如果有两个函数名是重名的,由于Python没有函数重载的概念,那么后面的定义会覆盖之前的定义,也就意味着两个函数同名函数实际上只有一个是存在的。这个时候模块的作用就体现出来了。

Python中的每个文件就代表了一个模块(module),在不同的模块中可以有同名的函数,在使用某个函数的时候可以通过import关键字引入指定的模块就可以区分每个函数了。

:定义两个模块,分别为module1module2,然后测试引入流程

module1

def printinfo():
     print("这是第一个模块的printinfo函数")

module2

def printinfo():
     print("这是第二个模块的printinfo函数")
  1. 使用import关键字直接引入

    import module1
    import module2
    # 通过模块名加.函数名的方式引入
    module1.printinfo()
    module2.printinfo()
    
  2. 使用import...as关键字重命名引入

    import module1 as m1
    import module2 as m2
    # 可以通过重命名后的名字加.函数名的方式引入
    m1.printinfo()
    m2.printinfo()
    
  3. 使用from...import...as关键字重命名引入某个函数

    from module1 import printinfo as p1
    from module2 import printinfo as p2
    # 可以通过重命名后的名字加.函数名的方式引入
    p1()
    p2()
    

    注意:这里如果不使用as进行重命名的话,因为有两个printinfo就会导致错误,所以需要为其重命名

__name__ == '__main__'的用法

__name__是Python中一个隐含的变量它代表了模块的名字,如果直接打印__name__,则出现__main__

示例代码module.py

def printinfo():
     print("这是函数内的内容")

print(__name__)
print("这是模块函数外的内容")

输出结果

# __main__
# 这是模块函数外的内容

如果将module.py作为模块引入则打印的结果为模块的名称(不带路径、扩展名)

示例代码

import module

输出结果

module
这是模块函数外的内容

此时输出的结果就不一样了,简单来说:在module.py自己眼中name就是main,然而在别的文件眼中name就是module

module.py改造一下

def printinfo():
     print("这是函数内的内容")

printinfo()
if __name__=="__main__":
     print(__name__)
     print("这是模块函数外的内容")

输出结果

这是函数内的内容
__main__
这是模块函数外的内容

当其他文件引入时

import module

输出结果

这是函数内的内容

因为其他文件引入时不会执行模块中if条件成立时的代码 因为模块的名字是module而不是__main__

__name__ == '__main__'在实际场景中非常有用,一般在写模块的过程中肯定要进行测试,在导入的时候肯定不能将测试结果也打印出来,如果删除了,想要改进模块的时候又要重新写一遍,这个时候__name__ == '__main__'就派上了用场

变量的作用域

def test():
     b = "这是函数的变量"
     def test_nested():
          c = "这是嵌套的函数变量"
          print(a)
          print(b)
          print(c)
     test_nested()

if __name__=="__main__":
     a = "这是全局作用域"
     test()

根据这段代码,来理解变量的作用域

此时在函数test_nested体内调用a,b,c三个函数都不会报出任何错误,

如果在函数体外调用b变量就会报出

	print(b)
NameError: name 'b' is not defined

变量b未定义的错误,因为b属于局部变量,属于局部作用域,在函数体外是访问不到的

如果在test函数体内调用c则会报出

    print(c)
NameError: name 'c' is not defined

变量c未定义的错误,因为c是在test_nested函数体内,对于test函数来说属于局部作用域,但是对于test函数内部的test_nested函数来说,变量b属于嵌套作用域,在test_nested函数中我们是可以访问到它的。

如果通过global来将b提升为全局变量,则在函数体外调用b变量就会正常打印

nonlocal关键字只能作用于局部变量,且始终找离当前最近的上层局部作用域中的变量

def outer():
     aa = 111
     def inner():
          nonlocal aa
          aa = 222
          print(aa)
     inner()
     print(aa)

outer()

如果没有这个nonlocal关键字则函数体inner打印222,函数体outer打印111,加上之后则直接打印两个222

  • Python查找一个变量时会按照“局部作用域”–>“嵌套作用域”–>“全局作用域”–>“内置作用域”的顺序进行搜索,所谓的“内置作用域”就是Python内置的那些标识符,之前用过的inputprintint等都属于内置作用域。

今日学习总结

  1. 函数的作用
  2. 定义函数的方法,以及return语句的作用
  3. 函数的参数,定义函数的时候的参数叫形参,传入的叫实参
  4. 将函数封装称为模块
  5. 变量的作用域,以及globalnonlocal关键字

明日学习计划

  • Python中字符串的使用

甜甜有话说

只有无限接近死亡,才能领悟生存的真谛,我的天啊,这个也太难了吧。弄了好久还是对nonlocal关键字不是很了解

座右铭:不要在该奋斗的年纪选择安逸!!

加油

感谢骆昊 (jackfrued) 大佬的教程——入口地址

古之立大事者,不惟有超世之才,亦必有坚忍不拔之志。——苏轼

猜你喜欢

转载自blog.csdn.net/weixin_46163658/article/details/105936522