从函数到包的Python代码层次
代码层次
Python是一门脚本语言,新建一个.py
文件,写点代码,就可以跑起来了,无论放哪都可以。比如where.py
文件:
print("Where am I?")
那么问题来了,这是写在哪里的呢?为了一目了然,我们用“导游图”的视角来看看代码层次:
红色箭头指出了,是写在模块中的,原来一个.py
文件就是一个模块。模块中可以写函数和类,模块可以放在包中。
函数
Python中最出名的函数一定是print()
了,毕竟全世界都在用它say Hello World。Python函数其实和数学中的函数很像,比如y = f(x)
。有函数名字、输入和输出。Python的函数结构如下:
函数通过def
关键字来定义:
def 函数名(参数列表):
函数体
参数列表有就有,无则无,多个参数用逗号分隔。例如:
def hello() :
print("Hello World!")
hello() # 调用函数
def max(a, b):
if a > b:
return a
else:
return b
a = 4
b = 5
print(max(a, b))
调用函数,不需要再加def
,直接函数名(参数列表)
即可。参数既可以是变量,也可以是其他函数,只要能一一对应。return
关键字用来返回值。return不是必需的,如果没有,那么函数会把内部代码全部都执行完再退出,如果有,函数会在return语句立刻退出,同时返回return语句的值,例如:
# 可写函数说明
def sum( arg1, arg2 ):
# 返回2个参数的和."
total = arg1 + arg2
print ("函数内 : ", total)
return total
print("这里不会执行!")
# 调用sum函数
total = sum( 10, 20 )
print ("函数外 : ", total)
类
为什么还要写类,函数它不香么?这个问题有点大,我只能简单解释一下,那就是因为,类是包括了函数的,如果有一天你发现函数不够用了,那么可以用类试试,哈哈哈。
类是面向对象编程中的概念,把对象中共性的东西抽离出来而成。
类中的函数叫做方法,除了方法还有属性(也就是变量),我写个不严谨的公式:类 = 属性 + 方法,例如:
class People:
#定义属性
name = ''
age = 0
#定义方法
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name, self.age))
类的使用跟函数一样,需要调用,例如:
dongfanger = People() # 这叫做实例化对象
dongfanger.speak() # 调用方法
类的一大好处是,可以通过继承来进一步复用代码。
模块
模块中可以包含模块级代码、函数和类。模块与模块之间是不能直接调用的,必须使用import
关键字来导入。导入时,模块级代码一定会被执行,如果我们不想让某些代码执行,那么可以添加一句if __name__ == '__main__':
,例如
if __name__ == '__main__':
print('这里的代码,仅在该模块自身运行时执行')
else:
print('模块被导入时执行')
函数和类需要调用才会运行,所以不存在这个问题。
包
包是一个目录,特殊的地方在于需要包含一个__init__.py
文件(内容可以为空),这是为什么呢?设想一下import hello
这条语句,Python从哪去找hello
这个包,C盘D盘E盘,成千上万个文件,范围太大了。所以需要把有Python模块的目录标出来,只查找这些目录就可以了。示例:
sound/ 顶层包
__init__.py 初始化 sound 包
formats/ 文件格式转换子包
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ 声音效果子包
__init__.py
echo.py
surround.py
reverse.py
...
filters/ filters 子包
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
命名空间
命名冲突是个头疼的问题,Python提供了命名空间这个方法,把代码块划分为不同的命名空间,同一个命名空间不能重名,不同命名空间可以重名,如图所示:
命名空间一般有三种:
- 内置:Python内置的名字。
- 全局:模块中定义的名字,包括模块的函数、类、其他导入的模块、模块级的变量和常量。
- 局部:函数中定义的名字,包括函数的参数和局部定义的变量。(类中定义的也是)
包里面是文件,文件名重复与否由操作系统判断。
作用域
命名空间决定了变量的作用域,小的作用域只在内部才有作用,比如函数内的变量,模块是不能用的:
def func():
a = 1
print(a) # 报错NameError: name 'a' is not defined
反之,大的作用域能作用到小的作用域:
a = 1
def func():
print(a)
func() # a = 1
如果不同作用域有相同名字的变量,Python的匹配顺序为:局部 -> 全局 -> 内置,例如:
a = 1
def func():
a = 2 # 不会作用到模块的a
func() # 调用函数修改a的值
print(a) # a的值仍为1
函数内部的a并不能影响到模块级别的a,因为Python在找a时,函数内部已经找到了,就不会再找了。
可以使用global
关键字,把局部变量定义为全局变量,这样模块级别的变量也可以在函数内修改了:
a = 1
def func():
global a # global声明为全局
a = 2
func() # 调用函数修改a的值
print(a) # a的值变为2
另外,Python中只有模块、类和函数,才会产生作用域。其他代码块如if
、while
、for
等是不会产生作用域的,也就是说这些语句内定义的变量,外部也可以访问,例如:
if True:
a = 1
print(a)
东方说
本文是Python入门系列这道前菜的最后一篇了,正餐Python进阶系列计划在2021年1月开始推送,具体计划我会写在元旦的一篇文章中。Python入门系列并不算完整的教程,它的定位是进阶篇的铺垫,做一些知识储备,降低阅读门槛。如果想学习完整教程,可以找菜鸟教程,也可以上B站看视频(个人更推荐)。最后,为了知识共享和传递,我把入门的7篇文章都导出成pdf上传了,可以在公众号后台回复“入门”下载哦。
参考资料:
https://www.runoob.com/python3/python3-function.html
https://www.runoob.com/python3/python3-class.html
从函数到包的Python代码层次的更多相关文章
- 让Chrome浏览器抓包接口数据秒变 python 代码
简介 uncurl是一个库,允许您将curl请求转换为使用requests 的python代码.由于Chrome网络检查器具有的“copy as cURL”,因此该工具对于用python重新创建浏览器 ...
- 常用正则表达式最强汇总(含Python代码举例讲解+爬虫实战)
大家好,我是辰哥~ 本文带大家学习正则表达式,并通过python代码举例讲解常用的正则表达式 最后实战爬取小说网页:重点在于爬取的网页通过正则表达式进行解析. 正则表达式语法 Python的re模块( ...
- python代码规范以及函数注释规范
摘要 本文给出主Python版本标准库的编码约定.CPython的C代码风格参见PEP7.本文和PEP 257 文档字符串标准改编自Guido最初的<Python Style Guide&g ...
- DeBug Python代码全靠print函数?换用这个一天2K+Star的工具吧,改进版
pysnooper是代码debug神器,比无限low print好很多和也比日志debug好一些,比断点调试也好一些,这个很犀利的装饰器. https://www.toutiao.com/a66829 ...
- 使用cython库对python代码进行动态编译达到加速效果及python第三方包的制作安装
1.测试代码:新建 fib.pyx # coding:utf-8 import matplotlib.pyplot as plt import numpy as np from sklearn.cl ...
- 常用统计分析python包开源学习代码 numpy pandas matplotlib
常用统计分析python包开源学习代码 numpy pandas matplotlib 待办 https://github.com/zmzhouXJTU/Python-Data-Analysis
- vscode设置python代码补全时函数自动加上小括号
vscode设置python代码补全时函数自动加上小括号 vscode的python代码补全插件默认安装时是不会自动补全括号的,感觉不是和方便 以下介绍下自动补上小括号的方法 可能部分同学设置了还是没 ...
- 使用bandit对目标python代码进行安全函数扫描
技术背景 在一些对python开源库代码的安全扫描中,我们有可能需要分析库中所使用到的函数是否会对代码的执行环境造成一些非预期的影响.典型的例如python的沙箱逃逸问题,通过一些python的第三方 ...
- 【转】Python 代码调试技巧
转载自:http://www.ibm.com/developerworks/cn/linux/l-cn-pythondebugger/ Debug 对于任何开发人员都是一项非常重要的技能,它能够帮助我 ...
随机推荐
- Linux(CentOS6.8)配置ActiveMQ
1.下载ActiveMQ http://activemq.apache.org/ 注:若是想下载老版本的ActiveMQ可以通过以下链接下载 http://activemq.apache.org/do ...
- php openssl 加密解密
$config = array( "digest_alg" => "sha512", "private_key_bits" => ...
- Docker学习第一天(Docker入门&&Docker镜像管理)
简介 今天小区的超市买零食老板给我说再过几天可能就卖完了我有点诧异,老板又说厂家不生产了emmm 今天总算开始docker了! 1.Docker? 1.什么是Docker Docker 是一个开源的应 ...
- MySQL第01课- CentOS + 单实例MySql编译安装总结
2016年2月,从oracle转向MySql ,碰上几个坑,特此记录 总结 1.注意环境变量.配置文件,操作过程不能出错 2.相比rpm方式安装,编译安装方式可以指定安装路径,再说安装是简单活,将来安 ...
- 凭借着这份Spring面试题,我拿到了阿里,字节跳动美团的offer!
一般问题 1.1. 不同版本的 Spring Framework 有哪些主要功能? 1.2. 什么是 Spring Framework? Spring 是一个开源应用框架,旨在降低应用程序开发 ...
- FL Studio采样设置之时间拉伸栏
今天小编将带领大家了解一下FL Studio采样设置页面中的时间拉伸栏知识,该栏目包含了和采样音频的时间拉伸相关的设置.其右边是一个时间伸缩方式下拉列表,里面列出了很多种类的伸缩方式,自动方式是默认的 ...
- 使用Camtasia制作我的观影报告
最近抖音兴起做<我的观影报告>风潮.<我的观影报告>是通过剪辑影片+旁白的方法,将自己观看过的影片安利给观众的方式.如果大家想要制作这类型的观影报告,建议使用Camtasia( ...
- 适合 Java 新手的开源项目集合——在 GitHub 学编程
作者:HelloGitHub--老荀 当今互联网份额最大的编程语言是哪一个?是 Java!这两年一直有听说 Java 要不行了.在走下坡路了.没错,Java 的确在走下坡路,未来的事情的确不好说,但是 ...
- Java —— for while do...while循环(1)
//for循环 for(初始化语句 ;循环条件; 迭代语句){ 循环体; } //while循环 初始化语句; while(循环条件){ 循环体; 迭代语句; } //do...while循环 初始化 ...
- HTTPS原理剖析
一.HTTP隐患 客户端向服务器发送HTTP请求,服务器收到请求后返回响应给客户端: 抓包如图: 我们可以发现:HTTP报文明文传输(而TCP/IP是可能被窃听的网络):且客户端跟服务器之间没有任何身 ...