前言导读:Python的创始⼈为吉多·范罗苏姆(Guido van Rossum)。 1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决⼼开发一个新的脚本解释程序,作为ABC语言的一种继承。其诞生于1990年;
一:基础常识
1.1:认识Python
1.1.1:Python能够干什么?
应用方向 | 描述 |
网路爬虫 | Google 等搜索引擎公司大量地使用 Python 语言编写网络爬虫。 |
数据分析 | 用爬虫爬到了大量的数据之后最终的目的就是分析数据。 |
机器学习 | 机器学习就是人工智能的一个分支,应用有自然语言处理,搜索引擎,各种识别技术,数据挖掘等等。 |
WEB应用开发 | 国内:豆瓣/知乎 国外:YouTube 使用的是Python作为WEB开发基础语言。 |
APP应用开发 | Python 可以开发OS X,Linux,Windows,iOS,Android 等平台的应用。 |
游戏开发 | Python开发的游戏几乎可以运行在所有常用的操作系统里面。 |
自动化脚本 | 频繁、重复、无脑的操作都可以使用Python脚本代替操作,以此节省大量时间 |
1.1.2:Python是什么语言?
>>>按照出现时间分类<<<
语言分类 | 描述 |
机器语言 | 由0和1组成的二进制串语言 |
汇编语言 | 由简洁的英文字母与符号串来替代一个特定的指令的二进制串,比如用"ADD"代表加法,"MOV"代表数据传递 |
高级语言 |
>>>按程序执行方式<<<
编译运行
把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快;
优点:执行时较快,因为已经全部编译好,不用一个一个执行编译
缺点:在不同系统中可能代码不能通用。
解释运行
只在执行程序时,才一条一条的解释成机器语言给计算机来执行,所以运行速度不如编译后的程序运行的快;
优点:只要通过编写一个程序,在不同的系统中只需要相对应的翻译器即可。
缺点:每次运行的时候都要解释一遍,性能上不如编译型语⾔言。(但python的程序能够在第一次运行时,将需要的包等文件拷贝到文件中,节省一定时间)
>>>按程序设计方法<<<
面向过程
最开始的语言是面向过程的。做一件事的顺序,程序设计的总体框架也是一件事的执行过程,而过程中每个部分包含执行动作的对象。
面向过程是一种以过程为中心的编程思想,它是一种基础的顺序的思维方式,面向对象方法的基础实现中也包含面向过程思想。
**特性**
模块化 流程化
**优点**
性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入 式开发、Linux/Unix等一般采用面向过程开 发,性能是最重要的因素。
**缺点**
没有面向对象易维护、易复用、易扩展
面向对象
后来的语言都包含对‘’类“的定义,也就是某一种对象。在执行中需要先将对象“实例化”(特指一类中的某一个对象),比如,将‘’狗“作为一个类,“小黑”(编程通常使用英文)作为一个狗的名字,也就是实例化。
**概念**
面向对象是按人们认识客观世界的系统思维方式,采用基于对象(实体)的概念建立模型,模拟客观世界分析、设计、实现软件的办法。通过面向对象的理念使计算机软件系统能与现实世界中的系统一一对应。
**特性**
抽象 封装 继承 多态
优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
缺点:性能比面向过程低
>>>按变量类型转换<<<
静态语言/强类型语言
静态语言是在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型。
强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。举个例子:如果你定义了一个整型变量a,那么程序根本不可能将a当作字符串类型处理。强类型定义语言是类型安全的语言。
例如:C++、Java、Delphi、C#
等。
动态语言/弱类型语言
动态语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。
数据类型可以被忽略的语言。它与强类型定义语言相反, 一个变量可以赋不同数据类型的值。强类型定义语言在速度上可能略逊色于弱类型定义语言,但是强类型定义语言带来的严谨性能够有效的避免许多错误。
例如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell
等等。
两者区别
区别一:特性
强类型语言是一旦变量的类型被确定,就不能转化的语言。变量类型分为强制类型转换和隐式类型转换切会损失精度.
弱类型语言则反之,一个变量的类型是由其应用上下文确定的。
区别二:静态语言的优势
由于类型的强制声明,使得IDE有很强的代码感知能力,故,在实现复杂的业务逻辑、开发大型商业系统、以及那些生命周期很长的应用中,依托IDE对系统的开发很有保障;
由于静态语言相对比较封闭,使得第三方开发包对代码的侵害性可以降到最低;
区别三:动态语言的优势
思维不受束缚,可以任意发挥,把更多的精力放在产品本身上;
集中思考业务逻辑实现,思考过程即实现过程;
总结:Python是一门_________________语言!
1.1.3:Python的特点
语法简洁:弱类型语言不多哔哔
可跨平台:只要能够安装解释器哪里都能运行
应用广泛:上到机器学习下到嵌入式
支持中文:Python3开始变量可以为中文当然不推荐,中文编程易语言
强制可读:通过强制缩进体现语句间的逻辑关系提高了程序的可读性
模式多样:语法层面同时支持面向过程和面向对象两种编程方式
粘性扩展:通过接口和函数集成其他语言编写的代码
开源理念:解释器众多,代码也能加密...
库类丰富:再造一个轮子也不嫌多
优点 | 缺点 |
易于阅读和维护 | 运行速度慢 |
可扩展性和可移植性 | 代码不能加密(使用pyinstall打包成EXE文件) |
有一个广泛的标准库 | |
GUI编程【图形化界面】 | |
支持各种主流数据库之间的交互 | |
可嵌入型【可以将python程序嵌入到c++中】 |
1.2:编程环境搭建
实验一:同一系统下安装Python2.7与Python3.9解释器...
实验二:安装破解版的Pycharm2021或者其他版本....
1.3:Hello World程序
1.3.1:基础知识点
- Python3默认的编码为unicode,utf-8可以看做是unicode的一个扩展集
- Python2默认的编码是ASCII,一般设置为UTF-8的编码格式
# -*- encoding:utf-8 -*-
- Python解释器的种类:
CPython/
IPython/
JPython/PyPy/IronPython
1.3.2:程序编写方式
- 进入cmd控制台. 输入python进入编辑模式. 这时候我们可以直接编写python程序
- 也可以在
.py
文件中编写python代码. 通过python命令来执行python代码
1.3.3:变量与常量
变量 | 将运算的最终结果暂存到内存中,以便后续程序调用 |
常量 | Python中不存在绝对的常量,约定俗称:所有字母大写就是常量,例如:PI |
变量命名规范:
1:python的变量必须由字母/数字/下划线组成
2:不能用纯数字,也不能数字开头
3:不能是python的关键字
4:变量名称不要太长
5:变量名称要有意义
6:变量名要区分大小写
8:不要使用中文(pyhton认中文/规范)
9:推荐使用驼峰或者是下划线命名(首字母大写)
驼峰体:除首字母外的其他每个单词首字母大写
下划线:每个单词之间用下划线分开
1.3.4:输出函数
>>>输出的三种方式<<<
- 表达式语句
- Print()函数
- 文件对象写入与读取
>>>Print()函数方法<<<
- 输出字符串和数字
>>>print("warsec") # 输出字符串
warsec
>>> print(100) # 输出数字
100
>>> str = 'warsec'
>>> print(str) # 输出变量
warsec
>>> L = [1,2,'a'] # 列表
>>> print(L)
[1, 2, 'a']
>>> t = (1,2,'a') # 元组
>>> print(t)
(1, 2, 'a')
>>> d = {'a':1, 'b':2} # 字典
>>> print(d)
{'a': 1, 'b': 2}
>>> print("\"Hello\"\n") # //将“Hello”进行转义输出并且使用\n进行换行操作
"Hello"
- 格式化输出整数,支持参数格式化,与 C 语言的 printf 类似
>>>str = "the length of (%s) is %d" %('warsec',len('warsec'))
>>> print(str)
the length of (warsec) is 6
符 号 | 描述 |
%c | 格式化字符及其ASCII码 |
%s | 格式化字符串 |
%d | 格式化整数 |
%u | 格式化无符号整型 |
%o | 格式化无符号八进制数 |
%x | 格式化无符号十六进制数 |
%X | 格式化无符号十六进制数(大写) |
%f | 格式化浮点数字,可指定小数点后的精度 |
%e | 用科学计数法格式化浮点数 |
%E | 作用同%e,用科学计数法格式化浮点数 |
%g | %f和%e的简写 |
%G | %f 和 %E 的简写 |
%p | 用十六进制数格式化变量的地址 |
- 格式化输出进制数
#%x --- hex 十六进制
#%d --- dec 十进制
#%o --- oct 八进制
>>>nHex = 0xFF
>>> print("nHex = %x,nDec = %d,nOct = %o" %(nHex,nHex,nHex))
nHex = ff,nDec = 255,nOct = 377
- 输出数据分隔符
print 会自动在行末加上回车, 如果不需回车,只需在 print 语句的结尾添加一个逗号 , 并设置分隔符参数 end,就可以改变它的行为。
>>>for i in range(0,6):
... print(i)
...
0
1
2
3
4
5
>>> for i in range(0,6):
... print(i, end=" ")
...
0 1 2 3 4 5
- Print不换行
在 Python 中 print 默认是换行的,想不换行你应该写成 print(i, end = '' )
>>> for i in range(1,6):
... print(i,end="")
...
12345>>>
1.3.5:Format用法
相对基本格式化输出采用‘%’的方法,format()功能更强大,该函数把字符串当成一个模板,通过传入的参数进行格式化,通过{}和:来代替传统%方式
- 使用位置参数
要点:从以下例子可以看出位置参数不受顺序约束,且可以为{},只要format里有相对应的参数值即可,参数索引从0开,传入位置参数列表可用*列表
>>> li = ['hoho',18]
>>> 'my name is {} ,age {}'.format('hoho',18)
'my name is hoho ,age 18'
>>> 'my name is {1} ,age {0}'.format(10,'hoho')
'my name is hoho ,age 10'
>>> 'my name is {1} ,age {0} {1}'.format(10,'hoho')
'my name is hoho ,age 10 hoho'
>>> 'my name is {} ,age {}'.format(*li)
'my name is hoho ,age 18'
- 使用关键字参数
要点:关键字参数值要对得上,可用字典当关键字参数传入值,字典前加**即可
>>> hash = {'name':'hoho','age':18}
>>> 'my name is {name},age is {age}'.format(name='hoho',age=19)
'my name is hoho,age is 19'
>>> 'my name is {name},age is {age}'.format(**hash)
'my name is hoho,age is 18'
- 填充与格式化
:[填充字符][对齐方式 <^>][宽度]
>>> '{0:*>10}'.format(10) ##右对齐
'********10'
>>> '{0:*<10}'.format(10) ##左对齐
'10********'
>>> '{0:*^10}'.format(10) ##居中对齐
'****10****'
- 精度与进制
>>> '{0:.2f}'.format(1/3)
'0.33'
>>> '{0:b}'.format(10) #二进制
'1010'
>>> '{0:o}'.format(10) #八进制
'12'
>>> '{0:x}'.format(10) #16进制
'a'
>>> '{:,}'.format(12369132698) #千分位格式化
'12,369,132,698'
- 使用索引
>>> li
['hoho', 18]
>>> 'name is {0[0]} age is {0[1]}'.format(li) //第一个0为format函数接收的第一个列表
'name is hoho age is 18
1.3.6: f-string 格式化字符串
在Python中,前面加上f
是为了创建格式化字符串为其前缀,也被称为f-string。这是Python 3.6及以上版本中的新特性。它可以用来格式化字符串的一种简洁方式,使得代码更易读。
name = "Alice"
age = 30
# 传统字符串格式化
message = "Hello, my name is " + name + " and I am " + str(age) + " years old."
# f-string格式化
message = f"Hello, my name is {name} and I am {age} years old."
print(message)
# 两种格式化方法都是生成相同的结果。但使用f-string的方法更简洁,更易读。
1.3.7:设置字符串打印颜色
格式:\033[显示方式;前景色;背景色m
说明:
前景色 背景色 颜色
---------------------------------------
30 40 黑色
31 41 红色
32 42 绿色
33 43 黃色
34 44 蓝色
35 45 紫红色
36 46 青蓝色
37 47 白色
显示方式 意义
-------------------------
0 终端默认设置
1 高亮显示
4 使用下划线
5 闪烁
7 反白显示
8 不可见
print("\033[1;31;40m","WebSite".center(60,'*')) #<!--1-高亮显示 31-前景色红色 40-背景色黑色-->
for i in range(1,50,2):
print(i,end=" ")
print("\033[0m") #<!--采用终端默认设置,即取消颜色设置-->
1.3.8:输入函数
Python3.x 中 input() 函数接受一个标准输入数据,返回为 string 类型
注意:在 Python3.x 中 raw_input() 和 input() 进行了整合,去除了 raw_input( ),仅保留了input( )函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。
语法格式:变量 = input("提示信息")
>>>接收单个值<<<
>>>a = input("input:")
input:123 # 输入整数
>>> type(a)
<class 'str'> # 字符串
>>> a = input("input:")
input:runoob # 正确,字符串表达式
>>> type(a)
<class 'str'> # 字符串
>>>接收多个值<<<
#!/usr/bin/python
#输入三角形的三边长
a,b,c = (input("请输入三角形三边的长:").split())
a= int(a)
b= int(b)
c= int(c)
#计算三角形的半周长p
p=(a+b+c)/2
#计算三角形的面积s
s=(p*(p-a)*(p-b)*(p-c))**0.5
#输出三角形的面积
print("三角形面积为:",format(s,'.2f'))
1.4:关键字与运算符
1.4.1:标识符与关键字
>>>标识符<<<
- 第一个字符必须是字母表中字母或下划线 _ 。
- 标识符的其他的部分由字母、数字和下划线组成。
- 标识符对大小写敏感。
>>>关键字<<<
保留字即关键字,我们不能把它们用作任何标识符名称。Python 的标准库提供了一个 keyword 模块,可以输出当前版本的所有关键字:
C:\Users\26629\Desktop>python39
Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', '__peg_parser__', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
>>>
1.4.2:单行与多行注释
# 第一个注释
# 第二个注释
'''
第三注释
第四注释
'''
"""
第五注释
第六注释
"""
print ("Hello, Python!")
1.4.3:行与缩进
Python 最具特色的就是使用缩进来表示代码块,不需要使用大括号 {}
。缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。缩进不一致,会导致运行错误。
if True:
print ("True")
else:
print ("False")
1.4.4:多行语句
Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠 \ 来实现多行语句
total = item_one + \
item_two + \
item_three
在 [], {}, 或 () 中的多行语句,不需要使用反斜杠 \
total = ['item_one', 'item_two', 'item_three',
'item_four', 'item_five']
1.4.5:数据类型
1.4.6:运算符
Python程序语言参与运算的数据成为操作数,表示运算的符号称为运算符。例如在加法运算中2+3中,2和3成为操作数而"+"称为运算符。
》》》算数运算符《《《
运算符 | 描述 | 示例 |
+ | 加:两个对象相加 | a+b输出结果为11(a=9,b=2) |
- | 减:两个对象相减 | a-b数据结果为7 |
* | 乘:两个对象相乘返回一个重复若干次的字符串 | a*b输出结果为18 |
/ | 除:a除以b | a/b输出结果为4.5 |
% | 取余:返回除法的余数 | a%b输出结果为1 |
** | 幂:返回a的b次幂 | a**b输出结果为81 |
// | 取整除:返回商的证书部分(向下取整) | a//b输出结果4 |
》》》赋值运算符《《《
基本的赋值运算符是"=",其作用是将运算符右边的值或计算结果赋给运算符左边。以下为复合赋值运算符!
运算符 | 描述 | 示例 |
+= | 加法赋值运算符 | b+=a 等效于b=b+a |
-= | 减法赋值运算符 | b-=a 等效于 b=b-a |
*= | 乘法赋值运算符 | b*=a 等效于 b=b*a |
/= | 除法赋值运算符 | b/=a 等效于 b=b/a |
%= | 取模赋值运算符 | b%=a 等效于 b=b%a |
**= | 幂赋值运算符 | b**=a 等效于 b=b**a |
//= | 取整数赋值运算符 | b//=a等效于 b=b//a |
》》》比较运算符《《《
比较运算符用来对操作数进行比较,其运算结果只有1或0,即条件成立时结果为1 不成立时结果为0
运算符 | 描述 | 示例 |
> | 大于:比较a是否大于b | a > b 返回True |
< | 小于:比较a是否小于b | a < b 返回False |
>= | 大于等于:比较a是否大于或等于b | a >=b 返回True |
<= | 小于等于:比较a是否小于或等于b | a <= b 返回False |
== | 等于:比较两个对象是否相等 | a == b返回False |
!= | 不等于:比较连个对象是否不相等 | a !=b 返回True |
》》》逻辑运算符《《《
逻辑运算符用来表示"并且""或者""非"等思想,通常用于组合条件语句!(以a=9 b=2为例)
运算符 | 逻辑表达式 | 描述 | 示例 |
and | a and b | 布尔"与":有一个假即为假 | a and b 返回2 |
or | a or b | 布尔"或":有一个真即为真 | a or b返回9 |
not | not a | 布尔"非":非真即假,非假即真 | not a返回False |
》》》运算符的优先级《《《
当多个运算符同时出现在一个表达式中,需要根据运算符的优先级顺序决定表达式中运算的执行顺序,以下表列出了运算符从高到低的优先级顺序!
运算符 | 描述 |
** | 指数(最高优先级) |
*/%// | 乘 除 取余 取整数 |
+- | 加减 |
<= < > >= | 小于或等于 小于 大于 大于或等于 |
== != | 等于 不等于 |
= %= /= //= -= += *= **= | 赋值运算符 |
not | 逻辑非 |
and | 逻辑与 |
or | 逻辑或 |
# 算数运算符:+ - * / %
print('算数运算符'.center(30, '*'))
a = 10
b = 3
print(a + b) #加:13
print(a - b) #减:7
print(a * b) #乘:30
print(a / b) #除:3.33333
print(a // b) #取整:3
print(a % b) #取余:1
print(a ** b) #指数:返回10的3次幂即1000
# 赋值运算符 += -= *= /= %= **= //=
print('赋值运算符'.center(30, '*'))
a +=b
print(a) # 13
a -=b
print(a) # 10
a *= b
print(a) # 30
a /= b
print(a) # 10.0
a %= b
print(a) # 1.0
a **= b
print(a) # 1.0
a //= b
print(a) #0.0
# 比较运算符 > >= < <= == !=
print('比较运算符'.center(30, '*'))
c = 10
d = 3
if c > d:
print(c > d)
elif c < d:
print(c < d)
elif c == d:
print(c)
# 逻辑运算符
print('逻辑运算符'.center(30, '*'))
if c > d and d > c:
print()
else:
print('有一个假即为假')
if c < d or d < c:
print('有一个真即为真')
if not d > c:
print('非真即假,非假即真')
1.5:字符串处理
字符串可以进行运算的操作:+
*
[]
[:]
in
not in
运算符 | 描述 |
+ | 链接运算符,用于拼接字符串 |
* | 重复运算符,用于重复输出字符串 |
[] | 访问运算符,通过索引访问字符串中的字符 |
[:] | 访问运算符,用于截取字符串中的一部分 |
in | 成员运算符,如果字符串中包含给定字符,则返回True |
not in | 成员运算符,如果字符串中不包含给定字符,则返回True |
# + 链接运算符
print(name_1+name_2+name_3)
# * 重复 运算符
print('-' * 10)
# [] 访问运算符
text = "hello world"
print(text[4])
# in成员运算符
rpText = "Command Execute Success! Result:AD\\administrator"
rsconn = "success"
if rsconn in rpText.lower():
print("命令成功执行!")
else:
print("命令执行失败!")
if rsconn not in rpText.lower():
print("命令执行失败")
else:
print("命令执行成功")
在Pyhon中一切皆对象,每一个字符串都是一个对象;
1:使用dir()可以查看对象的的使用方法
2:使用help()可以查看某个方法的帮助信息
备注:使用dir()方法回显的带下划线的是该对象的类,而不带下划线的则是对象的方法。
1.5.1:字符串切片操作
切片是截取其中的一部分,其语法格式为[开始:结束:步长]
其中,切片区间从"开始"位开始,到"结束"位的前一位结束(不包含结束位本身),当步长省略时,默认为1。若出现负数索引,则代表离尾部响应的距离的元素!
注意:索引值以 0 为开始值,-1 为从末尾的开始位置。
# 字符串的切片
string = "ABCDEF"
#print(字符串[开始:结束-1:步长])
print(string[0:3]) #截取索引0-2的字符
print(string[0:6:2]) #截取索引0-6且步长为2的字符
print(string[3:]) #截取索引从3开始到末尾的字符串
print(string[:5]) #截取从头开始到索引4的字符
print(string[::2]) #截取从头到尾步长为为2的字符
print(string[2:-1]) #截取从2开始到倒数第二个字符
print(string[::-3]) #截取从尾到头步长为3的字符
china = "我有着一颗中国心,我爱你中国" # 截取出:中国心,爱中国
print(china[5:9]+china[10]+china[-2:])
1.5.2:字符串处理方法
函数名 | 描述 | |
字母处理 | upper | 将字符串中所有的小写字母转换为大写字母 |
lower | 将字符串中所有的大写字母转换为小写字母 | |
capitalize | 将字符串中第一个字符转换为大写字母 | |
title | 将字符串中所有的单词首写字母转换为大写,其余字母小写 | |
swapcase | 对字符串的大小写字母进行互换 | |
搜索 | find | 检测字符串中是否包含子串,若没有则返回-1 |
index | 检测字符串中是否包含子串,若没有则会报错 | |
统计 | len | 计算字符串长度,既包含单个字符的个数 |
count | 统计字符串中指定字串出现的次数 | |
格式化 | ljust | 原字符串左对齐,并以特定字串填充至指定长度 |
rjust | 源字符串右对齐,并以特定字串填充至指定长度 | |
center | 源字符串居中对齐,并以特定字串填充至指定长度 | |
替换 | replace | 新子串替换旧子串,且次数不超过指定次 |
去指定字符 | lstrip | 删除字符串左边指定字符 |
rstrip | 删除字符串右边指定字符 | |
strip | 删除字符串左右两边指定字符 | |
split | 按照指定次数,以特定的字符分割字符串 | |
判断 | startswith | 检测字符串是否以指定子串开头 |
endswith | 检测字符串是否以指定子串结尾 | |
isalnum | 检测字符串是否由字母和数字构成 | |
isalpha | 检测字符串是否只由字母组成 | |
isdigit | 检测字符串是否只由数字组成 | |
isupper | 检测字符串中所有的字母是否均为大写 | |
islower | 检测字符串中所有的字母是否均为小写 | |
istitle | 检测字符串中所有的单词首字母是否为大写,且其他字母为小写 | |
isspace | 检测字符串是否只由空格组成 |
# upper/lower的作用是将字符串中所有小写/大写字母转换为大写/小写字母
string = 'Hello Python'
print('转换为大写'.center(15, "#"))
print(string.upper())
print('转换为小写'.center(15, "@"))
print(string.lower())
# find和index 检测字符串中是否包含子串且返回子串开始处的索引值。两者区别在于当不包含子串时,函数find返回-1,函数index返回异常
string = 'App and Application'
print(string.find('Application')) #8
print(string[string.find('Application'):])
print(string.find('APP')) #-1
#print(string.index('oi')) #找不到直接报错
print(string.title()) #设置单词的首字母为大写
#函数find和index在检测是否包含子串时还可指定检测范围,即在指定范围内是否包含该子串
# print(string.index("and", 0, 6)) #若在指定的范围内无法找到则报错
# print(string.find("and", 0, 7)) #若在指定的范围内无法找到则报错
#count用于统计是在字符串指定范围内子串出现的次数
print(string.count('App')) #默认在字符串长度内进行统计
print(string.count('App',0,6)) #在索引0-5范围内进行统计
#len计算字符串长度,既包含单个字符的个数
print(len(string)) #空格也算
#ljust/rjust/center 指分别将原字符串左对齐/右对齐/居中对齐/并以指定字符填充到指定长度
print('--------左对齐-------')
print(string.ljust(30, '*')) #函数第一个参数30为指定的新字符串长度,第二个参数'*'为填充字符,即在原字符串对其后,使用该字符将原字符串填充至指定新字符串的长度
print('--------右对齐-------')
print(string.rjust(30, '*'))
print('--------居中对齐-------')
print(string.center(30, '*'))
# replace可将原字符串中的旧子串替换成新子串,函数中第一个参数代表旧子串,第二个参数代表新子串,第三个参数代表替换次数,若第三个参数缺失则默认全部替换
newStirng = string.replace('App', 'Wow')
print(newStirng) #修改替换后的内容
print(string) #原本内容无变化
#stringConn = input("请输入你的留言内容:")
#print('您输入的内容为:'+stringConn.replace('操', '*'))
# lstrip rstrip strip 分别用于删除字符串左边/右边/左右两边的指定字符
string = ' App and Application'
print('[+]当前字符内容:'+string)
print('删除左边指定字符'.center(15, "*"))
print(string.lstrip())
string = ' App and Application*******'
print('[+]当前字符内容:'+string)
print('删除右边指定字符'.center(15, '*'))
print(string.rstrip('*'))
string = '******App and Application******'
print('[+]当前字符内容:'+string)
print('删除两边字符'.center(15, "*"))
print(string.strip('*')) #其中函数内的参数'*'表示删除指定的字符,在缺失情况下默认为空格
# split 利用指定字符按照指定次数分割字符串并返回分割字符串之后的列表
string = 'App and Application'
print(string.split()) #以空格为分隔符分割整个字符串
print(string.split('i')) #指定分隔符'i'分割整个字符串
print(string.split('a', 1)) #分割次数为1并指定分割符'a'将整个字符串分割为两个子字符串
#startswith endswith 分别用于检测字符串是否以指定子字符串开头/结尾,如果是返回True否则返回false
print(string.startswith('App')) #是否是以'App'字符作为开头
print(string.endswith('os')) # 是否以'os'字符作为结尾
print(string.endswith('and',0,7)) # 是否在0-7索引内似是以'and'字符作为结尾
print(string.endswith('And',0,7)) # 是否在0-7索引内似是以'and'字符作为结尾
# isalpha isdigit 分别检测字符串是否只由字母/数字组成,如果都是字母/数字组成则返回True否则返回false
string = 'Applistation'
print('当前'+string+'只由英文字符组成:'+str(string.isalpha()))
string = '手机Applistation'
print('当前'+string+'由中文与英文字符组成:'+str(string.isalpha()))
string = '手机Applistation!!!'
print('当前'+string+'由中文与英文和特殊字符组成:'+str(string.isalpha()))
string = '123456'
print('当前'+string+'只由数字组成:'+str(string.isdigit()))
string = 'No123456'
print('当前'+string+'只由数字组成:'+str(string.isdigit()))
1.6:列表/元组/字典/集合
1.6.1:列表
列表即等同于C语言的数组数据类型,唯一不同的是可以用来存储不同数据类型的变量...Python中没有数组而是用列表代替数组,列表由一系列按特定顺序排列的数据组成 并且这些数据类型可以是不同数据类型组成
(1)列表的创建
与创建变量的方法一样,列表可以使用等号赋值。列表中的所有元素存放在一对方括号中且元素之间用逗号分隔。
# 案例代码
age = [18,21,24] # 整数列表
money = [66.66,99.99] #小数列表
shop = ['香奈儿','Diao','LanK'] #字符列表
shopCar = [18,66.66,'香奈儿'] #不同数据类型
twolist = [age,money,shop,otherConn] #二维列表
otherConn = [] #空列表
print(age)
print(money)
print(shop)
print(shopCar)
print(otherConn)
print(twolist)
(2)列表的访问
列表是一个有序集合,要访问列表中的单个元素可以通过索引的方式。与字符串的索引相同...列表的索引也是从0开始,即第一个列表元素的索引为0而不是1;第二个列表元素的索引为1,以此类推...
另外,列表也可以通过负数索引访问元素。例如:当索引为-1时,可以访问列表中的最后一个元素!索引-2即倒数第二个元素,索引-3为倒数第三个元素,以此类推....
print(age[1])
print(money[1])
print(shop[2])
print(shop[-1])
print(shopCar[2])
print(twolist[1][1])
(3)列表的切片
利用索引可以每次从列表中获取一个元素,如果需要依次获取多个元素则可以通过列表切片实现。列表切片的语法格式与字符串切片相同,通过三个参数设定(start,stop-1,step)获取满足要求的部分列表元素。
number = [10,20,30,40,50,60,70,80]
print(number[2:5])
print(number[6:])
print(number[:3])
print(number[1:3])
print(number[::-2])
(4)列表元素查找
查找指定的元素是否存在列表中,与查找字符串中是否包含指定字符类似,均是Python提供的的成员运算符;
in:如果指定元素存在于列表中,则结果为True否则为False
not int:如果指定元素不存在于列表中,则结果为True否则为False
unlist = ['administrator','admin','system','iis','mssql']
username = input('请输入用户名:')
if username.lower() in unlist:
print("【+】当前用户为管理员用户!")
else:
print("【-】不存在高权限用户列表中...")
(5)列表元素修改
对列表中的元素进行修改时,其语法与访问列表中的元素相似。通过指定列表名和需要修改的元素索引,对列表中该索引位置的元素重新赋值,即可修改当前索引位置上的元素。即列表名[索引]=新元素来进行元素的修改!通过该方法可以修改列表中任意位置上元素的值!
string = ['Baidu','Google','Bing','Fofa']
print('修改之前的列表:'+str(string))
string[3] = 'SouGou'
print('修改之后的列表:'+str(string))
(6)列表元素添加
Python提供了多种在列表中添加元素的方式:append / extend / insert
* append方法可将新元素添加到列表末尾
* insert方法可在列表中任意指定位置处插入新元素
* extend方可一次性将另一个列表中的多个元素添加到当前列表的末尾
1.利用append添加元素
append方法可将新元素添加到列表末尾其一般形式为 list.append(element)
其中list为列表名,element为要添加的任何类型的元素
# 案例代码
string = ['Baidu','Google','Bing','Fofa']
print('修改之前的列表:'+str(string))
string.append('360So')
print('使用了append新增一个元素的列表'+str(string))
利用append方法可以动态创建列表。例如,先创建一个空列表,用于存储用户将要输入的数据,之后根据用户提供的每个新元素,用append方法不断添加到该列表中!
name = []
name.append('华夏')
name.append('故土')
name.append('传奇')
print(name)
2.利用insert添加元素
insert方法可在列表中任意指定位置处插入新元素,一般形式为:list.insert(index,obj)
其中list为列表名,index为要插入元素的索引位置,obj为要插入的元素。将新元素插入后的同时将之前从索引1位置开始到末尾的所有元素均右移一个位置。
# 案例代码
name = ['华夏', '故土', '传奇']
name.insert(1,'文明')
print(name)
3.利用extend添加元素
extend方可一次性将另一个列表中的多个元素添加到当前列表的末尾,其一般形式为:list.extend(seq)
其中 list为列表名,seq为要添加的元素列表。
# 案例代码
age = [10,20,30,40]
age.extend([50,60,70,80])
age.append([90,100])
print(age)
(7)列表元素删除
Python常用的列表删除方式有 del / pop / remove等
* del方法可以删除已知索引位置的元素或整个列表
* pop方法可以删除列表末尾的元素
* remove方法可以删除列表中指定值的元素
1.利用del删除元素
del方法可以删除已知索引位置的元素或整个列表,其一般形式为del list[index] 或del list
其中,list为列表名,index为元素索引!
# 案例代码
age = [10, 20, 30, 40, 50, 60, 70, 80, [90, 100]]
print(age)
del age[0] # 删除第一个元素
print(age)
del age[1:4] # 删除第一个元素到第三个元素
print(age)
del age #清空列表元素
print(age)
2.利用pop删除元素
pop方法可以删除列表末尾的元素,并且删除的的元素可以赋值给变量,从而依然能够被访问,其一般形式为:list.pop()
# 代码案例
command = ['reverse shell','net user','scaninfo']
print('列表内容为:'+str(command))
delete = command.pop()
print('当前删除的元素为:'+delete)
print('当前列表内容为:'+str(command))
3.利用remove删除元素
remove方法可以删除列表中指定值的元素,其一般形式为list.remove(obj)
这里需要注意:remove方法只删除改值在列表中的第一个匹配项,而不是所有的匹配项!
# 案例代码
rsinfo = ['root','www-data','tomcat','mysql','mysql']
print('当前列表的元素有:'+str(rsinfo))
rsinfo.remove('mysql')
print('删除\'mysql\'后的列表元素还有:'+str(rsinfo))
(8)列表排序
Python提供了几种排序方法,这几种方法可以轻松的对列表进行排序 sort sorted reverse
1.利用sort进行排序
sort方法用于对列表按照特定顺序重新排列,且默认从小到大排序;sort方法会修改列表元素的排列顺序且无法恢复到原来的排列顺序!
# 案例代码
list = [3,4,1,2]
list.sort()
print(list) #输出结果为[1, 2, 3, 4]
list.sort(reverse=True) # 从大到小排序,需要在sort方法中加入参数reverse=True
print(list) #输出结果[4, 3, 2, 1]
2.利用sorted排序
sorted方法可实现需要保留列表元素开始排列顺序,只是以特定顺序展示的功能!
使用sorted方法后,原始列表的元素顺序并未发生改变,另外sorted方法默认从小到大进行排序,如果需要按照从大到小显示列表可在sorted方法中加入参数reverse=True,与sort方法的降序使用方法类似!
list = [3,4,1,2]
listed = sorted(list)
print(list) # [3, 4, 1, 2]
print(listed) #[1, 2, 3, 4]
print(sorted(list, reverse=True)) #[4, 3, 2, 1]
* 注意:reverse方法与其他两种排序方法不同,并不按照大小关系排列元素而是对列表元素进行反向排序
* reverse方法对于修改列表顺序也是永久性的,但可以通过再次使用revese方法,可将列表恢复至原来的排列顺序!
(9)列表复制
复制列表时,常用的一种方法是:创建一个包含整个列表的切片,即在切片中省略所有索引值,则可得到从列表起始到列表末尾的所有元素,从而完成整个列表的复制!
# 案例代码
list = [3,4,1,2]
list_c = list[:]
print(list)
print(list_c)
(10)列表遍历
当需要对列表中的每个元素执行相同操作时,可使用for和while循环遍历列表
1.使用for循环遍历列表
利用for循环遍历列表时,可将列表作为for循环中的序列,获取其中每个元素!
# 案例代码
username = ['system','admins','administrator','iis-user']
for e in username:
print(e)
2.使用while循环便利列表
# 案例代码
username = ['system','admins','administrator','iis-user']
i = 0
while i < len(username):
print(username[i])
i += 1
* 程序通过len函数获取列表的长度,当循环控制变量i的值小于列表长度时,循环输出当前索引i位置上的元素,直到列表末尾!
1.6.2:元组
由于列表可以修改,因此适合于存储在程序运行期间元素可能变化的数据!然而有时候在程序中需要创建一系列不能修改的元素,因此Python提供了元组这种数据类型!元组简而言之,就是不可变的列表
;我们不希望其内容发生增删改,则采用元组的形式保存;
>>>元组的定义<<<
元组的元素不允许修改,但其变量的引用可以重新赋值
num = (200, 50)
print(num[:])
num[0] = 250 # 报错,元组中的元素不允许修改
num = (250, 50) # 修改num的指向
print(num[:])
>>>元组的遍历<<<
与列表相同,元组作为一种序列,也可以利用循环实现元组
name = ('孙悟空','500','如意金箍棒')
for e in name:
print(e)
name = ('孙悟空','500','如意金箍棒')
i = 0
while i < len(name):
print(name[i])
i += 1
1.6.3:字典
在列表中对某个特定元素进行操作时,需要利用索引获取该元素!但是当该元素位置发生变化时,其索引也会发生变化...此时需要首先修改程序中该元素的索引,才能够对元素进行操作!Python提供了一种数据类型--字典
不在需要通过索引访问元素,并且元素的位置改变时也不需要修改索引就能快速定位到该元素!其类似于JSON对象;采用{}内加键值对的方式;
(1)创建字典
字典使用大括号定义{} 由多个键及其相对应的值组合构成!键和值之间用冒号分割,键值对之间用逗号分割!字典的键必须唯一而值可以是任何数据类型!字典与序列的不同是序列讲究顺序,字典讲究一一对应而不关心顺序!
# 案例代码
info = {'name':'孙悟空','age':500,'other':'齐天大圣'}
print(info) #输出内容:{'name': '孙悟空', 'age': 500, 'other': '齐天大圣'}
(2)访问字典元素
需要访问字典中的某个值时,可根据键来获取,通过在字典名后的方括号内写入键则可得到字典中与该键相关的值! 如果使用不存在的键访问则程序会报错!
# 案例代码
print(info['name']) #孙悟空
print(info['age']) #500
print(info['other']) #齐天大圣
Python还提供了get方法,能够在不确定字典中是否存在某个键时访问其值!当键存在时,返回相对应的值,如果不存在时则返回None或这是的默认值!
print(info.get('name')) #孙悟空
print(info.get('ages', 1000)) #1000 在第二个参数设置了该键对应的默认返回值1000 如果ages不存在则返回!
(3)添加字典元素
跟列表一样,字典中可以添加新的键值对!键值对的顺序与添加顺序并不相同,再次说明字典不关心顺序,只关心键值之间的对应关系!
# 案例代码
info = {'name':'孙悟空','age':500,'other':'齐天大圣'}
info['Say'] = '如来 我XX你XX!'
info['Over'] = 'Over!'
print(info) # 输出结果:{'name': '孙悟空', 'age': 500, 'other': '齐天大圣', 'Say': '如来 我XX你XX!', 'Over': 'Over!'}
(4)修改字典元素
info = {'name':'孙悟空','age':500,'other':'齐天大圣'}
info['Say'] = '如来 我XX你XX!'
info['Over'] = 'Over!'
print(info)
info['Over'] = '就这些了'
print(info)
(5)删除字典元素
Python提供了两种方法删除字典中不在需要的信息
del方法:用于删除字典中指定的键值对
clear方法:用于一次性删除所有字典元素
1.使用del方法删除
info = {'name':'孙悟空','age':500,'other':'齐天大圣'}
del info['age']
print(info) # 输出打印{'name': '孙悟空', 'other': '齐天大圣'}
2.使用clear方法删除
info = {'name':'孙悟空','age':500,'other':'齐天大圣'}
info.clear()
print(info) # 输出打印{} clear方法清空了字典中所有的元素
3.列表与字典删除操作
# 列表删除 del pop remove
list = [1,2,3,4]
list_1 = list[:]
print(list)
#del(list) # 清空
del(list[0]) #删除第一个元素
del(list[0:2]) #删除第0 1个下索引的元素
print(list)
list_1.pop()
print(list_1) # 删除最后一个
list_1.remove(2)
print(list_1)# 删除名为2的元素
# 字典删除 del clear
dict = {'name':'龙龙','age':500}
del(dict['name'])
print(dict) # 删除指定键的值
dict.clear()
print(dict) # 清空字典键值对
(6)字典遍历
同序列一样,字典的遍历也可以通过for循环来是现实!
dict = {'name':'唐三藏','age':'九世轮回','other':'历经九九八十一难'}
# 遍历列表 拿取键值对
for key,value in dict.items():
print('key is %s,value is %s'%(key,value))
* 其中iteams方法返回字典的键值对列表,因此可以作为循环中的序列使用,之后的每个键值对分别赋值给key和value两个循环控制变量中!
# 遍历列表 拿取键
for key in dict.keys():
print('key is %s,value is %s'%(key,dict[key]))
* keys方法返回字典的键列表,之后将每个键赋值给循环控制变量key中!
# 遍历列表 拿取值
for value in dict.values():
print('value is %s'%value)
* values方法返回字典的值列表,之后将每个值赋值给循环控制变量!
>>>字典的嵌套/列表中的字典<<<
blog = {'title' : {'python': 'dict'} }
print(blog['title'])
print(blog['title']['python']) //打印维子弹当中的值
# list中的字典
blogList = [];
blogList.append(blog)
print(blogList)
1.6.4:集合
集合(set)是一个无序的不重复元素序列。可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
创建格式:
变量名 = {value01,value02,...}
或者
set(value)
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket) # 这里演示的是去重功能
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket # 快速判断元素是否在集合内
True
>>> 'crabgrass' in basket
False
>>> # 下面展示两个集合间的运算.
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # 集合a中包含而集合b中不包含的元素
{'r', 'd', 'b'}
>>> a | b # 集合a或b中包含的所有元素
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # 集合a和b中都包含了的元素
{'a', 'c'}
>>> a ^ b # 不同时包含于a和b的元素
{'r', 'd', 'b', 'm', 'z', 'l'}
>>>集合基操<<<
添加元素:s.add( x )
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.add("Facebook")
>>> print(thisset)
{'Taobao', 'Facebook', 'Google', 'Runoob'}
##################分界线###################
更新元素:s.update( x )
可以添加元素,且参数可以是列表,元组,字典等
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.update({1,3})
>>> print(thisset)
{1, 3, 'Google', 'Taobao', 'Runoob'}
>>> thisset.update([1,4],[5,6])
>>> print(thisset)
{1, 3, 4, 5, 6, 'Google', 'Taobao', 'Runoob'}
>>>
##################分界线###################
移除元素:s.remove( x )
将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误。
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.remove("Taobao")
>>> print(thisset)
{'Google', 'Runoob'}
>>> thisset.remove("Facebook") # 不存在会发生错误
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'Facebook'
>>>
移除元素:s.discard( x )
移除集合中的元素,且如果元素不存在,不会发生错误。
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.discard("Facebook") # 不存在不会发生错误
>>> print(thisset)
{'Taobao', 'Google', 'Runoob'}
随机删除集合中的元素:s.pop()
thisset = set(("Google", "Runoob", "Taobao", "Facebook"))
x = thisset.pop()
print(x)
##################分界线###################
清空集合:s.clear()
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.clear()
>>> print(thisset)
set()
##################分界线###################
判断元素是否在集合中存在:x in s
判断元素 x 是否在集合 s 中,存在返回 True,不存在返回 False。
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> "Runoob" in thisset
True
>>> "Facebook" in thisset
False
>>>
方法 | 描述 |
为集合添加元素 | |
移除集合中的所有元素 | |
拷贝一个集合 | |
返回多个集合的差集 | |
移除集合中的元素,该元素在指定的集合也存在。 | |
删除集合中指定的元素 | |
返回集合的交集 | |
返回集合的交集。 | |
判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。 | |
判断指定集合是否为该方法参数集合的子集。 | |
判断该方法的参数集合是否为指定集合的子集 | |
随机移除元素 | |
移除指定元素 | |
返回两个集合中不重复的元素集合。 | |
移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。 | |
返回两个集合的并集 | |
给集合添加元素 |
1.7:选择与循环
三大基本结构:顺序结构/选择结构/循环结构
1.7.1:控制语句
# 单分支
if 判断条件:
语句块
# 双分支
if 判断条件:
语句块a
else:
语句块b
# 多分支
if 判断条件1:
语句块1
elif 判断条件2:
语句块2
elif 判断条件n:
语句块n
......
else:
语句块n+1
# 判断嵌套
if 判断条件1:
if 判断条件2:
语句块1
else:
语句块2
else:
if 判断条件3:
语句块3
else:
语句块4
>>>IF语句<<<
if True:
print("Hello World")
print("Goog Bye")
------------------------
Hello World
Goog Bye
if False:
print("Hello Python")
print("Goog Bye")
------------------------
Goog Bye
>>>If...else语句<<<
if False:
print("No executed")
else:
print("Executed")
------------------------
Executed
>>>If...elif...else语句<<<
age = int(input("Please your age>>:"))
if 0 < age and age <= 20:
print("teenager")
elif 20 < age and age <= 40:
print("Man")
elif 40 < age and age <= 60:
print("Old")
else:
print("Died")
------------------------
Please your age>>:30
Man
>>>IF嵌套<<<
age = int(input("Please your age>>:"))
if age >= 0:
if 0 < age and age <= 20:
print("teenager")
elif 20 < age and age <= 40:
print("Man")
elif 40 < age and age <= 60:
print("Old")
else:
print("Died")
else:
print("Your age error")
-------------------------
Please your age>>:48
Old
# 这是一个简单的猜数字游戏的Python实现
import random
# 初始化一个随机数字
number = random.randint(1, 100)
# 游戏循环
while True:
# 提示用户输入一个数字,并尝试转换成整数
try:
guess = int(input("请输入一个数字(1-100): "))
except ValueError:
print("无效输入,请输入一个整数。")
continue
# 判断用户输入的数字是否正确
if guess == number:
print("恭喜你,猜对了!")
break # 游戏结束
elif guess < number:
print("猜的数字小了。")
else:
print("猜的数字大了。")
# 游戏结束后,可以选择继续或退出
play_again = input("要继续玩吗?(y/n) ")
if play_again.lower() == 'y':
number = random.randint(1, 100) # 重新生成一个随机数字
print("好的,下一轮你的目标是:", number)
else:
print("谢谢玩家!再见!")
1.7.2:循环语句
>>>While循环<<<
Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。
# 语法格式
while 判断条件:
语句块
如果关键字while后面的条件判断为真时,则开始执行循环体内的语句块,之后重复判断条件是否为真从而构成循环,知道条件不在满足时,循环结束在执行之后的程序!
# 案例代码-1
i = 1
while i <= 4:
print(i)
print('循环正在执行第%d次'%i)
i += 1 #条件控制
示例代码-2
sum = 0
count = 0
while count <= 100:
sum += count
count += 1
print(sum)
-------------------------
5050
示例代码-3
while无限循环,可以使用 CTRL+C 来中断循环
while True:
print("无限循环")
# 案例代码
情景:孩子的年龄是13岁,爸爸的年龄是33岁,问:过多少年后,爸爸的年龄是孩子年龄的两倍?
# 代码示例
agekid = 13
agedad = 33
count = 0
while agedad != agekid * 2:
agekid += 1
agedad += 1
count += 1
print('过%d年后,爸爸的年龄是孩子年龄的两倍'%count)
>>>For循环<<<
for循环可以遍历任何序列的项目(一个列表或者一个字符串等)
语法结构:
for <variable> in <sequence>:
<statements>
else:
<statements>
示例代码1:
languages = ["C", "C++", "Perl", "Python"]
for x in languages:
print (x)
示例代码2:
fruits = ['banana', 'apple', 'mango','tomato','pelar']
for fruit in range(len(fruits)):
print('fruit: ',fruits[fruit])
------------------------------------------------
fruit: banana
fruit: apple
fruit: mango
fruit: tomato
fruit: pelar
示例代码3:
for i in range(1,11):
print("192.168.0."+str(i))
- range()函数
Python提供了一个内置函数range,它能够生成一个数字序列常用于for循环中其语法格式为range(start,stop,step)其中start为计数初始值,stop为计数结束值,step为步长,三个参数必须为整数不能是浮点数等其他类型!
# 一般可分为以下三种形式
1.range(stop):在start缺失的情况下默认从0开始到stop结束,但不包括stop,例如range(5)等价于range(0,5)生成序列为[0,1,2,3,4]
2.range(start,stop):从start开始到stop结束但不包括stop。例如"range(1,5)"生成序列[1,2,3,4]且不包括5
3.range(start,sotp,step):从start开始,到stop结束,间隔为步长,在步长确实的情况下默认为1且不可为0.例如range(1,5,2)生成序列[1,3]从1开始到5-1结束 且前后两个数字的间隔步长为2
# 案例代码
print(list(range(5))) #[0,1,2,3,4]
print(list(range(1, 5))) #[1,2,3,4]
print(list(range(0, 10, 2))) #[0, 2, 4, 6, 8]
print(list(range(0, -5, -1))) #[0, -1, -2, -3, -4]
print(list(range(2, 0))) #[]
for e in range(1, 11):
print(e)
print('循环正在执行第%d次'%e)
其中range函数生成的序列为[1,2,3...10]。循环控制变量i从序列中依次取值,首先取值为1并执行循环体内的语句块,分别输出当前循环控制变量e的值,已经循环正在执行第几次;一直取到值10 循环一共执行10次且输出10次循环控制变量e的值!结果如下
>>>循环嵌套<<<
与if嵌套类似,Python允许一个循环内嵌套另一个循环。
# for循环嵌套
for 变量1 in 序列:
语句块
for 变量2 in 序列:
语句块
# while循环嵌套
while 判断条件1:
语句块
while 判断条件2:
语句块
# 执行顺序说明
a.首先判断最外层循环条件,如果条件成立则进入第一层循环
b.进入第一层循环后,若遇到嵌套的第二层循环则进行条件判断,若满足条件则进入第二层循环
c.若有多层循环嵌套,则依照上述方法依次判断是否进入内层循环
d.有内而外执行循环操作,若只有两层循环嵌套,则先执行内层循环体内的语句块
e.内层循环变量更新,返回步骤b执行,直到不满足进入内层循环条件
f.外层循环变量更新,返回步骤a执行,直到不满足进入外层循环条件
g.彻底退出循环嵌套
# 案例代码
情景:使用嵌套循环打印99乘法表!
# 程序代码
# 99乘法表
row = 1 #行数
while row < 10: #99乘法表只有9行
col = 1 #1列
while col <= row: #当列数小于等于行数开始循环
result = col * row # 列数 * 行数
print('%d * %d = %d\t'%(row, col, result),end='') #打印结果
col = col + 1 # 列数+1
print('\n')
row = row + 1 #行数+1
>>>Break语句<<<
break 语句可以跳出 for 和 while 的循环体。若遇到break而使得 for 或 while 循环中终止而且 else 块将不执行。
示例代码1:
for megs in 'Hello Python':
if megs == 'y':
break
print ('输出的当前字母为 :',megs)
--------------------------------
输出的当前字母为 : H
输出的当前字母为 : e
输出的当前字母为 : l
输出的当前字母为 : l
输出的当前字母为 : o
输出的当前字母为 :
输出的当前字母为 : P
示例代码2:
counts = 0
while counts < 6:
print("counts:" ,counts)
if counts == 3:
break
counts += 1
---------------------------------
counts: 0
counts: 1
counts: 2
counts: 3
>>>Continue语句<<<
continue语句被用来告诉Python跳过当前循环块中的剩余语句,然后继续进行下一轮循环
代码示例1:
for megs in 'Hello Python':
if megs == 'y':
continue
print ('输出的当前字母为 :',megs)
--------------------------------
输出的当前字母为 : H
输出的当前字母为 : e
输出的当前字母为 : l
输出的当前字母为 : l
输出的当前字母为 : o
输出的当前字母为 :
输出的当前字母为 : P
输出的当前字母为 : t
输出的当前字母为 : h
输出的当前字母为 : o
输出的当前字母为 : n
代码示例2:
counts = 0
while counts < 6:
counts += 1
if counts == 3:
continue
print("counts:", counts)
--------------------------------
counts: 1
counts: 2
counts: 4
counts: 5
counts: 6
>>>else子句<<<
循环语句可以有 else 子句,它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被break终止时不执行!
for...else :for 循环中使用 break 语句,break 语句用于跳出当前循环体,且不执行else子句,否则执行else子句
sites = ["Baidu", "Google","UC","Taobao"]
for site in sites:
if site == "Baidu":
print("李彦宏")
break
print("循环数据 " + site)
else:
print("没有循环数据!")
print("完成循环!")
--------------------------------
李彦宏
完成循环!
while...else语句:在条件语句为 false 时执行则else 的语句块,若遇到break语句则不执行else子句
count = 0
while count < 10:
print (count, " 小于 10")
count = count + 1
else:
print (count, " 大于或等于 10")
-------------------------
0 小于 10
1 小于 10
2 小于 10
3 小于 10
4 小于 10
5 小于 10
6 小于 10
7 小于 10
8 小于 10
9 小于 10
10 大于或等于 10
>>>Pass语句<<<
Python pass是空语句,是为了保持程序结构的完整性。pass 不做任何事情,一般用做占位语句
for char in "Hello World":
if char == 'W':
pass
print("执行pass语句")
print("char: " ,char)
------------------------------
char: H
char: e
char: l
char: l
char: o
char:
执行pass语句
char: W
char: o
char: r
char: l
char: d
import os
# 要求:做一个用户登录界面
# 用户交互
username = input("Enter your name: ")
password = input("Enter your password: ")
# 功能处理
username = username.lower()
password = password.lower()
if username == "admin" and password == "admin":
print("Welcome Admin".center(50,'*'))
while True:
command = input("请输入要执行的OS Command(q键退出):")
if command.lower() != 'q':
print(os.system(command))
else:
break
else:
print("Error Username or Password")
二:其他操作
2.1:文件操作
>>>基本流程<<<
- 用
open()
函数打开文件,并创建一个file对象; - 用file对象的read()或write()等方法,对文件内容进行读写操作;
- file对象的close()方法,关闭并保存文件内容。
>>>文件操作<<<
- 概念
文件是计算机中数据持久化存储的表现形式
- 基本语法
# 格式一(手工关闭文件):
file = open("文件名","读写模式")
...
file.close() # 关闭文件
# 格式二(自动关闭文件):
with open("文件名","读写模式") as file:
...
注意:文件操作完毕后必须关闭,否则内存将长时间保持对文件的连接状态,造成内存溢出的现象发生
- 文件的读写模式
读写模式 | 数据基本读写单位 | 操作权限 | 注意事项 |
rb | 字节 | 读 | 读取信息,如果文件不存在报错 |
wb | 字节 | 写 | 写入信息覆盖原始信息,如果文件不存在则新建 |
ab | 字节 | 追加写 | 写入信息到原始信息的末尾,如果文件不存在则新建 |
rb+ | 字节 | 读/写 | 读取信息,如果文件不存在报错 |
wb+ | 字节 | 读/写 | 写入信息覆盖原始信息,如果文件不存在则新建 |
ab+ | 字节 | 读/追加写 | 写入信息到原始信息的末尾,如果文件不存在则新建 |
r | 字符 | 读 | 读取信息,如果文件不存在则报错 |
w | 字符 | 写 | 写入信息覆盖原始信息,如果文件不存在则新建 |
a | 字符 | 追加写 | 写入信息到原始信息的末尾,如果文件不存在则新建 |
r+ | 字符 | 读/写 | 读取信息,如果文件不存在则报错 |
w+ | 字符 | 读/写 | 写入信息覆盖原始信息,如果文件不存在则新建 |
a+ | 字符 | 读/追加写 | 写入信息到原始信息的末尾,如果文件不存在则新建 |
- 写文件操作
函数名 | 功能 | 参数 | 返回值 |
Write(str) | 将指定信息写入文件中 | str:要写入的字符串信息 | 写入的数据总量 |
Writelines(model) | 将指定信息写入文件中 | model:要写入的存储模型信息,模型中数据是字符串 | 无 |
- 读文件操作
函数名 | 功能 | 参数 | 返回值 |
read() | 读取文件中所有信息 | 无 | 文件中的所有信息 |
read(num) | 读取文件中指定数量的字符/字节信息 | num:每次读取的数据总量 | 文件中指定数量的信息 |
readline() | 读取文件中的一行信息,以\n判定行是否读取完毕 | 无 | 文件中的一行信息 |
readlines() | 将文件中信息以行为单位读取到列表中,以\n判定行是否读取完毕 | 无 | 由文件中所有信息组成的列表对象 |
>>>文件路径<<<
- 概念
文件在计算机存储器(例如硬盘)中保存的位置称为文件路径 - 文件路径的分类
- 相对路径
从程序运行所在的目录位置描述文件的保存路径/从当前路径开始的路径称之为相对路径 - 绝对路径
从系统定义的存储位置描述文件的保存路径/以根开始的路径称之为绝对路径
eg:
a.txt # 相对路径
E:/b/c/a.txt #绝对路径
>>>代码示例<<<
向文件写入内容
>>> f=open("d:/king.txt","w")
>>> f.write("192.168.1.1")
>>> f.write("192.168.1.2")
>>> f.write("192.168.1.3")
>>> f.close()
##################分界线###################
向文件追加内容
>>> f=open("d:/king.txt","a")
>>> f.write("192.168.1.4\n")
>>> f.write("192.168.1.5\n")
>>> f.close()
##################分界线###################
read()方法可以一次性读取文件的所有内容
>>> f=open("d:\king.txt","r")
>>> f.read()
'192.168.1.1\n192.168.1.2\n192.168.1.3\n192.168.1.4\n192.168.1.5\n'
>>> f.close()
read()方法也可以指定读取前几个字节的数据
>>> f.read(12) //指定读取文件的前12个字节
'192.168.1.1\n'
##################分界线###################
readline()方法可以从文件中读取一行并作为返回结果返回
>>> f.readline()
'192.168.1.2\n'
>>> f.readline()
'192.168.1.3\n'
##################分界线###################
readlines方法是返回一个列表,文件的每一行作为列表的一个元素
>>> f.seek(0)
>>> f.readlines()
['192.168.1.1\n', '192.168.1.2\n', '192.168.1.3\n', '192.168.1.4\n', '192.168.1.5\n']
>>> f.readlines()
[]
##################分界线###################
seek()方法可以将指针返回到指定的位置
>>> f.seek(0)
>>> f.readline()
'192.168.1.1\n'
>>>
>>> f.seek(0)
>>> f.readlines()[0]
'192.168.1.1\n'
##################分界线###################
通过for循环对列表进行迭代,这是最常用的读取方法
>>> f=open("d:\king.txt","r")
>>> for i in f.readlines():
... print i
...
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5
>>> for i in f.readlines():
... print i.strip("\n")
...
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5
##################分界线###################
Windows文件中每行只有\n,而linux文件每行有\r和\n
for i in f.readlines():
print i.strip("\r\n")
2.2:网络连接
Socket是什么?
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。
2.2.1:套接字编程
Socket层的位置:Socket在传输层和应用层之间;
>>>套接字分类<<<
- 基于文件类型的套接字家族;套接字家族的名字:AF_UNIX
- 基于网络类型的套接字家族;套接字家族的名字:AF_INIT
>>>套接字流程<<<
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
2.2.2:Python套接字编程
Python提供了两个基本的Socket模块:
1:Socket,提供了标准的BSD Sockets API。
2:SocketServer,提供了服务器中心类可以简化网络服务器的开发。
>>>Socket类型<<<
套接字格式:socket(family,type[,protocal])
使用给定的地址族、套接字类型、协议编号(默认为0)来创建套接字。
socket类型 | 描述 |
socket.AF_UNIX | 只能够用于单一的Unix系统进程间通信 |
socket.AF_INET | 服务器之间网络通信,使用IPV4 |
socket.AF_INET6 | 服务器之间网络通信,使用IPV6 |
socket.SOCK_STREAM | 流式socket , for TCP |
socket.SOCK_DGRAM | 数据报式socket , for UDP |
socket.SOCK_RAW | 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。 |
socket.SOCK_SEQPACKET | 可靠的连续数据包服务 |
创建TCP Socket: | s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) |
创建UDP Socket: | s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) |
>>>Socket函数<<<
注意点:
1)TCP发送数据时,已建立好TCP连接,所以不需要指定地址。UDP是面向无连接的,每次发送要指定是发给谁。
2)服务端与客户端不能直接发送列表,元组,字典。需要字符串化repr(data)。
socket函数 | 描述 | |
服务端socket函数 | ||
s.bind(address) | 将套接字绑定到地址, 在AF_INET下,以元组(host,port)的形式表示地址. | |
s.listen(backlog) | 开始监听TCP传入连接。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 | |
s.accept() | 接受TCP连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。 | |
客户端socket函数 | ||
s.connect(address) | 连接到address处的套接字。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。 | |
s.connect_ex(adddress) | 功能与connect(address)相同,但是成功返回0,失败返回errno的值。 | |
公共socket函数 | ||
s.recv(bufsize[,flag]) | 接受TCP套接字的数据。数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。 | |
s.send(string[,flag]) | 发送TCP数据。将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。 | |
s.sendall(string[,flag]) | 完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 | |
s.recvfrom(bufsize[.flag]) | 接受UDP套接字的数据。与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 | |
s.sendto(string[,flag],address) | 发送UDP数据。将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。 | |
s.close() | 关闭套接字。 | |
s.getpeername() | 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 | |
s.getsockname() | 返回套接字自己的地址。通常是一个元组(ipaddr,port) | |
s.setsockopt(level,optname,value) | 设置给定套接字选项的值。 | |
s.getsockopt(level,optname[.buflen]) | 返回套接字选项的值。 | |
s.settimeout(timeout) | 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) | |
s.gettimeout() | 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。 | |
s.fileno() | 返回套接字的文件描述符。 | |
s.setblocking(flag) | 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。 | |
s.makefile() | 创建一个与该套接字相关连的文件 |
>>>Socket编程思路<<<
1. TCP服务端
1 创建套接字,绑定套接字到本地IP与端口
# socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.bind()
2 开始监听连接
#s.listen()
3 进入循环,不断接受客户端的连接请求
#s.accept()
4 然后接收传来的数据,并发送给对方数据
#s.recv() , s.sendall()
5 传输完毕后,关闭套接字
#s.close()
2.TCP客户端
1 创建套接字,连接远端地址
# socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.connect()
2 连接后发送数据和接收数据
# s.sendall(), s.recv()
3 传输完毕后,关闭套接字
#s.close()
>>>Socket之服务端代码<<<
Tcp_Server.py文件
"""
服务端
使用 socket 模块的 socket 函数来创建一个 socket 对象。
socket 对象可以通过调用其他函数来设置一个 socket 服务。
可以通过 bind(hostname, port) 函数来指定服务的 port(端口)。
接着,我们调用 socket 对象的 accept 方法。该方法等待客户端的连接,并返回 connection 对象,表示已连接到客户端。
"""
import socket # 导入 socket 模块
s = socket.socket() # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 8000 # 设置端口
s.bind((host, port)) # 绑定端口
s.listen(5) # 等待客户端连接
while True:
client, addr = s.accept() # 建立客户端连接
print("连接地址:", addr)
while True:
data = client.recv(1024) # 接收数据
print('server:', data.decode()) # 打印接收到的数据
client.send(data.upper()) # 然后再发送数据
client.close() # 关闭连接
>>>Socket之客户端代码<<<
Tcp_client.py文件
"""
客户端
socket.connect(hostname, port) 方法打开一个 TCP 连接到主机为 hostname 端口为 port 的服务器。
连接后我们就可以从服务端获取数据,记住,操作完成后需要关闭连接。
"""
import socket # 导入 socket 模块
# s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# s.connect("127.0.0.1", 8000)
# s.send(b"Hello World")
client = socket.socket() # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 8000 # 设置端口号
client.connect((host, port)) # 初始化 TCP 服务器连接
while True:
msg = '欢迎来到麻花屋!' # strip默认取出字符串的头尾空格
client.send(msg.encode('utf-8')) # 发送一条信息 python3 只接收btye流
data = client.recv(1024) # 接收一个信息,并指定接收的大小 为1024字节
print('client:', data.decode()) # 输出我接收的信息
s.close() # 关闭连接
>>>Socket发送HTTP请求<<<
import socket # 导入 socket 模块
client = socket.socket() # 创建 socket 对象
client.connect(("www.baidu.com", 80))
http = b"GET / HTTP/1.1\r\nHost: www.baidu.com\r\n\r\n"
client.send(http) # 初始化 TCP 服务器连接
data = client.recv(1024) # 接收一个信息,并指定接收的大小 为1024字节
print("recv: ", data.decode())
client.close() # 关闭连接
2.3:模块导入
模块就是用一堆的代码实现了一些功能的代码的集合,通常一个或者多个函数写在一个.py文件里,而如果有些功能实现起来很复杂,那么就需要创建n个.py文件,这n个.py文件的集合就是模块
>>>系统模块<<<
在你安装python之后,它自己内部的lib文件下就有很多模块可以用,导入后就可以使用,通常路径是C:\Python27\Lib (27是版本号,如果是3.9的版本就是C:\Python39\Lib)
>>>第三方开源模块<<<
>>>模块安装<<<
- 在线安装:python -m pip install 模块名称
- 本地安装:setup.py build #编译源码 --> setup.py install #安装源码
>>>模块导入<<<
#主要包括以下几种导入方式:
1、import moduels(模块名字) #导入整个模块,这种导入方式比较占用内存
2、import moduels (模块名字) as XX #这里是导入整个模块的同时给它取一个别名,因为有些模块名字比较长,用一个缩写的别名代替在下次用到它时就比较方便
3、from modules(模块名字) import func(方法) #从一个模块里导入方法,你要用到模块里的什么方法就从那个模块里导入那个方法,这样占用的内存就比较少
也可以用别名表示 : from modules(模块名字) import func(方法)as XX
4、from package.modules import func(方法) #从一个包的模块里导入方法 这个方法跟上面那种基本一样,占用的内存也比较少
也可以用别名表示,from modules(模块名字) import func(方法)as XX
导入模块其实就是告诉Python解释器去解释那个py文件
导入一个py文件,解释器解释该py文件
导入一个包,解释器解释该包下的 __init__.py 文件
>>>模块导入的路径<<<
模块导入的路径是以什么为标准的呢,就是以sys.path来查看!
>>> import sys
>>> print(sys.path)
['', 'D:\\setup\\python39\\python39.zip', 'D:\\setup\\python39\\DLLs', 'D:\\setup\\python39\\lib', 'D:\\setup\\python39', 'D:\\setup\\python39\\lib\\site-packages']
>>>
如果你要导入的模块不在这些路径下面,你就可以用sys.path.append('你要导入的绝对路径')
>>>模块的加载顺序<<<
模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块
1、在第一次导入某个模块时(比如spam),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用;
ps:python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules查看;
2、如果没有,解释器则会查找同名的内建模块;
3、如果还没有找到就从sys.path给出的目录列表中依次寻找spam.py文件。
2.4:def函数
如果将是现某个功能的代码抽象成一个函数,则之后在程序中多次执行同一项任务时,直接调用能够完成该任务的函数即可,从而使得程序的编写/阅读性和维护都更容易,程序的条理性会更清晰!Python提供了内建函数(print split sort)之外,用户还可以自定义函数!由用户根据实际需要自己的设计用来实现指定功能!函数的主要目的:封装一个功能
# 函数优点
1. 减少代码的重复率
2. 增强代码的可阅读性
1.函数的定义与调用
# 基本语法
def 函数名称(参数列表)
"函数_文档字符串"
函数体
retuen 表达式
# 函数定义规则说明
* 函数使用关键字def开头,后接函数名称和圆括号
* 函数的参数需要放在圆括号中
* 若参数列表中包含多个参数,在一般情况下参数值和参数名称按照函数声明中定义的顺序一一匹配
* 函数内容以冒号开始,并且缩进
* 函数的第一行语句成为文档字符串,用来描述函数功能,可选择性的写入
* 函数体表示函数功能,指定函数完成响应的操作!
* return表达式表明函数结束,并且选择性的返回一个值给调用方,如果return后没有表达式则相当于返回None
# 案例代码
def rce_poc(url):
'漏洞测试POC'
print(url)
return
* 其中rce_poc为函数名,传输参数为url,函数体内完成的操作是打印输出该字符串并且返回值为None
如果需要使用该函数功能则需要调用该函数,函数的调用通过函数名()的方式即可
# 定义函数
def rce_poc(url):
'漏洞测试POC'
print(url)
return
# 调用函数
url = 'http://www.baidu.com'
rce_poc(url)
>>> def add(x,y): #关键字,函数名,括号,冒号
... return x+y #终止函数的继续并返回一个值
...
>>> add(3,5) #执行函数 函数名+括号
8
2.函数参数
从调用角度来说,函数参数可分为形式参数和实际参数。其中,函数名后圆括号内的参数称为形式参数简称形参;调用函数时传递给函数的参数称之为实际参数,简称实参!
由于函数定义时可能包含多个形参,函数调用时可能包含多个实参,因此,在函数调用时传递参数的方式有很多!
(1)位置实参
位置实参需将函数调用时的实参,与函数定义的形参数量匹配且按照顺序一一对应。
# 函数定义
def poc(url,command):
print('攻击测试的目标为:'+url)
print('将要执行的命令为:'+command)
return
# 函数调用
poc('http://www.baidu.com/','whoami')
*利用位置实参调用函数时候,如果实参顺序有误,则结果会和预期不符!
*如果调用时传递的实参数量斯奥与形参数量,程序会出现语法错误!
(2)关键字实参
位置实参需要正确的按照参数吮吸传递数据,而关键字参数允许函数调用时传递的数据与参数顺序不一致!通过在实参中将参数名和值相关联,从而避免像函数传递实参时因顺序错误而导致程序运行结果不一致!
# 案例代码
def poc(url,command):
print('攻击测试的目标为:'+url)
print('将要执行的命令为:'+command)
return
# 函数调用
poc(url='http://www.google.com/',command='id')
# 命令执行结果
攻击测试的目标为:http://www.google.com/
将要执行的命令为:id
* 关键字实参在使用时不需要指定顺序,因为Python能够明白各个值应该存放到那个形参中!
(3)默认形参
定义函数时,可以给形参设置默认值。之后调用函数时,由于默认形参已经有值,所以是否传入实参不是必须的,而其他形参传入相对应的实参,当没有给默认形参提供是实参时,则直接使用形参的默认值,否则将使用提供的参数值;
# 案例代码
def poc(url,command='whoami'):
print('攻击测试的目标为:'+url)
print('将要执行的命令为:'+command)
return
# 函数调用
poc(url='http://www.Bing.com/') #调用默认形参
poc(url='http://www.google.com/',command='id')
* 使用默认形参时,在形参列表中默认形参应放到最后,前边应为没有默认值的形参,否则程序会报错!
(4)不定长参数
定义函数时,如果需要函数能够处理比定义时数量更多的参数,可采用不定长参数;格式如下,formal_args为普通形参,**args_tuple和**args_dict为不定长参数。
# 语法格式
def 函数名([formal_args,] **args_tuple,**args_dict)
"函数_文档字符串"
函数体
return 表达式
调用函数时,函数传入的实参会优先一一对应普通形参,如果实参参数与普通形参数量相同,不定长参数会返回空元组或空字典,如果是参数多于普通形参可以分为以下两种情况
1.如果实参没有指定名称而只有值,则Python会创建一个名为args_tuple的空元组,将接收到的数量多余普通形参的实参以值的形式一一放入元组中!
2.如果实参指定了名称以及值,如a=1,则Python会创建一个名为args_dict的空字典,将接收到的数量多于普通形参的实参以键值对的形式一一放入字典中!
# 案例代码
def exp(url, command, * args_tuple, **args_dict):
print(url)
print(command)
print(args_tuple)
print(args_dict)
print('分割线'.center(15,'*'))
return
exp('百度','whoami')
exp('百度','whoami','存在漏洞是','rceRs')
exp('百度','whoami','存在漏洞是','rceRs',DBSinfo='yes')
3.返回值
在调用python自带的len函数时,必须用一个变量来接收这个值。
str_len=len('hello,word')
使用自己写的函数也可以做到这一点
# 函数定义
def my_len():
s1='hello world'
length=0
for i in s1:
length=length+1
print(length)
str_len=my_len() #函数调用
print('str_len:%s'%str_len)
# 11
# str_len:None 说明这段代码什么都没有返回。
在写函数的时候,要尽量以功能为向导,结果最好不要直接在函数中打印出来。
关键字Return的作用:
- 返回一个值
- 终止一个函数的继续
def my_len(): # 函数名的定义
s1='hello world'
length=0
for i in s1:
length=length+1
return length # 函数的返回值
str_len=my_len() #函数的调用以及返回值的接收
print(str_len)
# 11
没有返回值:
- 不写return与写入return None的效果相同,返回的只都是None
- 只写一个return后面不加任何东西的时候与写return None的效果一样
返回多个值:
- 当用一个变量接收返回值的时候,收到的是一个元组。这是因为在python中把用逗号分割的 多个值认为是一个元组。
- 当返回值有多个变量接收,那么返回值的个数应该和接收变量的个数完全一致。
- return还有一个特殊的用途,一旦执行到return,后面的语句就不在执行了(结束一个函数)。(和break类似但有区别,break是跳出循环,如果循环后有代码则继续执行。return是结束整个函数)
- 如果在函数中有多个return,只执行第一个return。
def func():
return "a" , "b" #返回多个值时接收到的是一个元组
c = func() # c接收的是一个元组
print(c)
##('a', 'b')
###########
#返回多个值,用多个变量接收(接收的变量数与返回值的个数要一致)
def func():
return "a" , "b" , "c"
d , e , f = func()
print(d , e , f)
##a b c
def func():
return [1,2,3]
a , b , c = func() #列表和元组是可以解包的
print(a,b,c)
##1 2 3返回的字典类型有点意外:
def func(): return {"name":"span"}dic = func() #需要字典类型来接收,而不能直接用k,v,字典解包解出来的只是键print(dic)##{'name': 'span'}
4.匿名函数
所谓匿名函数,即没有名称的函数 也不再使用def定义函数。定义匿名函数时需要使用关键字lambda!
# 语法格式
lambda arg1,aeg2,...:expression
其中arg1等表示函数参数,函数参数可以有多个,expression代表表达式
# 案例代码
result = lambda num1,num2: num1*num2
print(result(1,2))
# lambda函数与def函数区别
1.def创建函数需要指向函数名称,而lambda函数没有函数名称
2.lambda函数冒号后米娜只能有一个表达式,而def函数可以包含语句块
3.lambda函数返回一个对象,而不会将结果直接赋值给一个变量,def函数可以通过return 表达式将结果直接赋值给一个变量!
4.lambda函数一般用于定义简单的函数,可精简程序。提高程序可读性,而def函数可以定义复杂的函数
>>>运行环境判断<<<
python为我们内置了全局变量__name__,文件被当做脚本执行时:__name__ 等于'__main__',文件被当做模块导入时:__name__等于模块名,其作用是用来控制.py文件在不同的应用场景下执行不同的逻辑。Py程序文件分为独立运行的状态或者是在被调用的状态!
>>> print (__name__) //私有的变量
__main__
>>>