Python编程基础——变量、函数、语句

本文详细介绍了Python编程的基础知识,包括变量的类型和使用,特别是高级变量如列表、元组、字典和字符串。讨论了局部和全局变量的概念,以及函数的基本语法、函数模块和返回值。此外,还涵盖了判断语句和循环语句的应用。
摘要由CSDN通过智能技术生成

“人生苦短,我用Python”,在渗透测试领域Python是高效的工具开发利器,基于Python可以快速编写信息爬取、文件处理、网络发包等脚本,而且现在多数poc/exp都用Python开发,Python几乎成为渗透测试领域的硬核技能,现把Python基础语法总结如下,方便复习查阅。

一、变量

理解变量“引用”的概念,Python中变量和数据是分开存储的,利用id()函数可以查看数据在内存中的地址 。赋值语句a=1,可理解为计算机在内存中分配了一个地址,地址中存放的值是1,变量a引用了这个地址。令b=a,可以发现id(a)==id(b),这是因为变量b也引用了这个地址,如果再令b=2,则内存中会新分配一个地址存放2,变量b再引用这个新的地址。

(一) 类型及基本使用

  • 变量类型:
    数字型:整型、浮点、布尔、复数
    非数字型(高级变量,容器):字符串、列表、元祖、字典

  • 使用type()函数可以查看变量的类型

  • 直接赋值,Python是弱类型语言,会自动定义变量类型,无需声明

  • 数字型变量之间可以直接计算

  • 使用input()接收用户输入,接收的内容为字符串类型,需要其他类型则需要转换,如int()float(),为节省内存优化代码,建议使用height = float(input("请输入身高:"))的形式

  • print()函数默认在输出内容结尾自动加上换行符,如果不希望自动增加换行,可以利用代码print("Hello", end=""),如果需要其他符号作为结尾则需要给end赋值,如print("Hello", end="---")

  • 格式化输出有两种方式:
    ① 利用格式化字符:%s %d %f %x,字符串与变量之间用%分隔,如:print("格式化字符串" % (变量1, 变量2...)),其中 (变量1, 变量2...)本质上是一个元祖
    ② 利用字符串对象的format方法,如:print("插入{}内容:{}".format(1,{"key":"value"})),format()方法中的参数可以是多个不同类型的变量

  • PEP8规范建议变量命令用下划线命名法,如:temp_variable

  • \t制表符用于将输出文本垂直方向保持对齐

  • CPython是官方使用c语言开发的python解释器

  • Python在运行时,内存首先加载解释器,然后从上至下逐行代码解释运行

  • del删除变量,可以释放变量分配的内存空间

(二) 高级变量的使用

1.列表

Python语言中使用最频繁的高级变量类型,索引从0开始编号,用[]定义,例如:

name_list = ["Jim", "Tom", "Alice"]

列表方法包括:

方法作用返回值
append(object)在列表末尾追加对象None
extend(seq)在列表末尾追加序列None
count(object)统计某个对象在列表中出现的次数int
index(object)从列表中找出某个对象第一个匹配项的索引int
pop()移除列表中最后一个对象,并返回该对象object
reverse()反转列表排序None
sort([reverse=False])列表排序,默认升序,降序令reverse=FalseNone
insert(index, obj)将对象插入列表索引index位置None
remove(object)移除列表中第一个匹配的对象None

只需要知道有哪些功能,无需死记硬背,在编辑器中通过提示就可以查看,比如在ipython中定义列表后,可用Tab键提示进行查看。

注意:虽然列表可以存储不同类型的数据,但是一般只存储相同类型数据,最常用迭代循环方法进行相同处理

2.元祖

与列表类似,区别在于:

  • 其定义时用()
  • 在定义之后不能再修改
  • 通常保存不同类型的数据
name_tuple = ("Jim", 18, 165)

元祖因为不能修改所以方法比列表少很多,只剩下count()和index(),使用方法和列表相同。

元祖和列表之间的转换:

  • 如果希望元祖可以修改,转换:num_list = list(num_tuple)
  • 如果希望列表不可以修改,转换:num_tuple = tuple(num_list)
3.字典

使用{},以{key:value}方式进行定义,键key是索引,值value是数据,键和值之间使用:分隔,键必须是唯一的,限定字符串、数字或元祖,值可以是任何类型,如:

name_dict = {"Jim": 18, 
             "Alice": 20,
             "Bob": 12}

字典方法包括:

方法作用返回值
clear()删除字典内所有内容None
copy()复制字典并返回该字典dict
get(key)返回字典中键为key的值(对象)object
update(dict)把字典dict的内容更新到原字典中,既可以合并字典,又可以更新键值None
keys()返回字典中所有键,后续可用list转换为列表dict_keys
values()返回字典中所有值,后续可用list转换为列表dict_values
pop(key)删除字典key对应的值,并返回该值(对象)object
popitem()删除并返回字典中最后一个键值对object

字典与列表的区别主要在于:

  • 列表将存储的内容用顺序索引对应起来,通过索引查找内容
  • 字典存储的内容(值)用键来对应起来,把键当成索引去查找内容

为字典中键值对本质上是无序的,所以在遍历字典时,输出的内容也是无序的,遍历时for key in dict中,key是字典的键。

更常见的应用场景是将多个键值对构成一个字典,多个字典组成一个列表,利用循环体对列表进行相同操作。

4.字符串

字符串方法非常多,按功能主要分为六种:

① 查找和替换,具体如下:

方法作用返回值
find(str)返回str在字符串中第一次出现的索引位置,如果不存在str则返回-1int
rfind(str)从字符串右边开始寻找int
index(str)与find相同,但是如果不存在str则会报错int
startwith(str)判断是否以指定的字符串开始,是则返回True,不是则返回Falsebool
endwith(str)判断是否以指定的字符串结束,是则返回True,不是则返回Falsebool
replace(str, repl)把字符串中所有str替换成repl,并不会修改原字符串str

② 拆分和连接,具体如下:

方法作用返回值
split([sep=’ '[, maxsplit]])以sep为分隔符拆分string,默认为空白符,包括\r\t\n以及空格,如果maxsplit有指定值,则仅分隔maxsplit+1个子字符串,前maxsplit个按照规则分隔,最后剩下的字符串分隔为一个整体,最后返回字符串列表List[str]
str.join(seq)以字符串str为分隔符将字符串序列seq中所有的元素(以字符串表示)合并为一个新的字符串str

③大小写转换,具体如下:

方法作用返回值
lower()转换字符串中所有大写字母为小写str
upper()转换字符串中所有小写字母为大写str

④ 判断字符类型,具体如下:

方法作用返回值
isalnum()判断字符串中至少有一个字符并且所有字符都是字母或数字则返回True,否则返回Falsebool
isalpha()判断字符串中至少有一个字符并且所有字符都是字母则返回True,否则返回Falsebool
isdigit()判断字符串中至少有一个字符并且所有字符都是数字则返回True,否则返回Falsebool
isnumeric()判断字符串中只包含数字字符(包括罗马数字和汉字数字)则返回True,否则返回Falsebool
islower()判断字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写则返回True,否则返回Falsebool
isupper()判断字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写则返回True,否则返回Falsebool
isspace()判断字符串中只包含空白符,包括\r\t\n以及空格,则返回True,否则返回Falsebool

⑤ 文本对齐,具体如下:

方法作用返回值
ljust(width[, fillchar=’ '])字符串左对齐,并用fillchar字符向右补齐到width宽度,fillchar默认为空格str
rjust(width[, fillchar=’ '])字符串右对齐,并用fillchar字符向左补齐到width宽度,fillchar默认为空格str
center(width[, fillchar=’ '])字符串左对齐,并用fillchar字符向两边补齐到width宽度,fillchar默认为空格str

⑥ 去除空白字符,具体如下:

方法作用返回值
strip(chars)删除字符串两侧的指定字符串,默认为空白符,包括\r\t\n以及空格str
lstrip(chars)删除字符串左侧的指定字符串,默认为空白符,包括\r\t\n以及空格str
rstrip(chars)删除字符串右侧的指定字符串,默认为空白符,包括\r\t\n以及空格str
5.容器的共同特点:

所有非数字型变量(列表、元祖、字典、字符串)都是一个序列,也可以理解为容器,容器有许多共同特点如:

  • 可以用[]取值
  • 遍历 for in
  • 计算长度、最大/最小值、比较、删除
  • 链接+和重复*
  • 切片

① python内置函数:len、del、max、min

  • len():统计容器中元素个数
  • del():删除容器
  • max():返回容器中最大值,如果是字典,只返回key的最大值
  • min():返回容器中最小值,如果是字典,只返回key的最小值

② 切片支持的容器类型包括列表、元祖、字符串

通过 容器[开始索引:结束索引:步长] 进行切片:

  • 注意序列的第一个元素索引为0
  • 步长即有间隔的进行切片,逆序的步长为-1
  • -index为倒序索引,最后一个元素索引为-1,如果要切到末尾,则结束索引为空即可

例如:

[0,1,2,3,4,5][1:3] -> [1,2]
[0,1,2,3,4,5][::-1] -> [5,4,3,2,1,0]
[0,1,2,3,4,5][-1:-3:-1] -> [5,4]

③ 运算符

  • innot in:列表、元祖、字典、字符串
  • *+->===:列表、元祖、字符串

(三) 局部变量和全局变量

1.定义

局部变量:在函数内部定义的变量

全局变量:在函数外部定义的变量

2.变量的生命周期

变量的生命周期指变量被创建到被系统回收的时间:

  • 局部变量在函数执行时被创建,在函数运行结束后被系统回收

  • 全局变量在解释器解析运行时就被创建,在程序运行结束后被系统回收

3.变量的作用域

作用域也叫命名空间:

  • 局部变量的作用域仅为函数内部

  • 全局变量(包括模块中定义的全局变量)的作用域为整个程序

4.全局变量使用规则

不推荐使用全局变量,因为全局变量可变范围太大,程序不好维护,例如如果程序员甲修改了a的值,程序员乙同时也要使用a,这时可能导致程序中的错误。

Python规定:只能在函数内部引用全局变量,但是不允许使用赋值语句修改全局变量的值,如果使用赋值语句,则只会在函数内部自动新生成一个局部变量,此变量并不是我们要修改的全局变量。

gl_num = 10

def demo1():
    gl_num = 99
    print("num is %d" % gl_num)

def demo2():
    print("num is %d" % gl_num)
    
demo1()
demo2()

输出结果:

num is 99
num is 10

函数内部调用变量时,有局部变量就会输出局部变量,没有的话才会向上寻找全局变量。

如果函数内部确需要对全局变量进行修改,这时要用global事先声明,这样函数就不会当成局部变量生成,如上述代码修改为:

gl_num = 10

def demo1():
    global gl_num
    gl_num = 99
    print("num is %d" % gl_num)

def demo2():
    print("num is %d" % gl_num)
    
demo1()
demo2()

输出结果:

num is 99
num is 99
5.全局变量定义习惯

(1) 定义全局变量的位置

建议将模块中的所有全局变量,定义在所有函数的上方,以便函数可以访问到变量,一般代码结构如下:

— shebang
— import modules
— global variables
— def functions
— executing code

(2) 全局变量命名的建议

建议在下方加上g_gl_global_,加以区分,避免和普通变量混淆。

二、函数

(一) 基本语法和注释

def name(chch, times)
    """注释
    
    :param chch asdf
    :param times: qwer
    """
    code

注意:

  • 函数要遵循先定义、再使用的原则,Python解释器首先要知道函数的定义,然后才能执行函数

  • Pycharm调试中step intostep over的区别,都是单步执行,但step into会跳进函数内部执行

  • Pycharm在view->quick document中可以查看函数的注释说明,快捷键Ctrl+Q,可以利用此方法查看函数的使用方法和释义

  • PEP8规范建议在函数定义的上方和其他代码保持两个空行

  • Pycharm中,光标放在函数位置,选择小灯泡,选择insert document stub,会自动生成带参数说明的标准注释

(二) 函数模块

1.定义
  • 以py结尾的源码文件都是模块

  • 模块中定义的全局变量和函数都是能给外界直接使用的工具

2.使用方法
  • module.variable

  • module.function

  • module.module

3.运行原理
  • 首先处理源代码,编译生成一个二进制字节码

  • 在对字节码进行处理,生成CPU能够识别的机器码

4.pyc文件

python解释器在运行时会将导入的模块源码转换为字节码,保存在__pycache__目录下,遇到关键字import,检查源文件和字节码文件的时间戳,如果相同,则直接加载pyc字节码文件,跳过编译过程,以优化执行速度。

(三) 函数的返回值和参数

1.函数的返回值
  • 函数可以通过return返回多个数据,比如元祖、字典和列表,当返回元祖时,可以将()去掉
  • 元祖、字典和列表既可以作为一个整体返回,也可以同时给多个变量赋值
def demo():
    name = "Jim"
    age = 10
    return name,age

aa, bb = demo()
cc = demo()

print(aa)
print(cc)

输出结果:

'Jim'
('Jim', 10)
2.函数的参数

因为Python解释器可以自动判断变量类型,因此函数无需定义返回值类型,函数的形参也无需定义类型。函数内部针对形参赋值,并不会改变实参的值,如以下语句:

gl_num = [1,3,4]

def demo(num):
    num = [5,6]
    return num

print(demo(gl_num))
print(gl_num)

输出结果:

[5,6]
[1,3,4]

程序运行时,首先在内存中为全局变量gl_num开辟出一个空间,执行到demo函数时num形参会指向这个空间,当重新给num赋值时,Python会新开辟一个空间,形参重新指向新的空间,成为新的引用,函数执行完num变量以及其指向的空间也随之释放。

但是如果函数传递的形参通过调用方法对自身进行修改,那么一样会影响实参,因为没有赋值语句,形参并没有指向新的引用。

gl_num = [1,3,4]

def demo(list_num):
    list_num.append(5)
    return list_num

print(demo(gl_num))
print(gl_num)

结果输出:

[1, 3, 4, 5]
[1, 3, 4, 5]
3.函数的缺省参数

(1) 基本使用

  • 定义函数时,给某个参数指定一个默认值,具有默认值的参数即为缺省参数

  • 调用参数时,如果没有传入缺省参数的值,则在函数内部使用定义函数时指定的参数默认值,从而简化函数的使用

指定函数的缺省参数,在定义函数的参数使用赋值语句即可:

def print_info(name, gender = True):
    if gender == True:
        print("%s is man" % name)
    else:
        print("%s is woman" % name)
 
print_info("Jim")
print_info("Aimy", False)

输出结果:

Jim is man
Aimy is woman

(2) 定义缺省参数的注意事项

  • 缺省参数应该放在函数参数的最后位置

  • 在调用具有多个缺省参数的函数时,指定缺省参数应该指定参数名,避免赋值顺序错乱

(3) 多值参数

有时可能需要一个函数能够处理的参数个数是不确定的,这个时候,就可以使用多值参数,Python中有两种多值参数:

  • 参数名前增加*可以接收元祖,习惯用*args

  • 参数名前加**可以接收字典,习惯用**kwargs

def demo(name, *age, **info):
    print("name is {}".format(name))
    print("args is {}".format(age))
    print("kwargs is {}".format(info))

demo(1, 2, 3, 4)
demo(1, 2, 3, country="CN")

输出结果:

name is 1
args is (2, 3, 4)
kwargs is {}

name is 1
args is (2, 3)
kwargs is {'country': 'CN'}

(4) 元祖和字典的拆包

在调用带有多值参数的函数时,如果希望:

  • 将一个元祖变量,直接传递给args
  • 将一个字典变量,直接传递给kwargs

就可以使用拆包,简化参数的传递,拆包的方式是:

  • 在元祖变量前,增加*
  • 在字典变量前,增减**
def demo(*num, **person):
    print(num)
    print(person)
    
gl_num = (1,2,3)
gl_dict = {"name":"Jim", "age":18}

demo(gl_num, gl_dict)
demo(*gl_num, **gl_dict)

输出结果:

((1, 2, 3), {'name': 'Jim', 'age': 18})
{}

(1, 2, 3)
{'name': 'Jim', 'age': 18}
4.函数的递归

函数调用自身的编程技巧称为递归

(1) 递归函数的特点

  • 函数内部代码是相同的,只是针对参数不同,处理的结果不同
  • 当参数满足一个条件时,函数不再执行,通常被称为函数的出口,不然会出现死循环(非常重要)
def sum_number(num):
    print(num)
    if num == 1:
        return
    sum_number(num-1)

sum_number(5)

(2) 递归案例——计算数字累加

def sum_numbers(num):
    if num == 1:
        return 1
    temp = sum_numbers(num-1)
    return temp + num

递归在处理不确定的循环条件时格外有用,例如遍历整个文件目录的结构。

三、语句

(一) 判断语句

判断语句if:

if condition:
    print...
else:
    print...

注意:

  • 缩进Tab和空格不能混用
  • 如果条件很长如if () or () or () or(),这样代码可读性较差,可在逻辑运算外加上括号,括号内的代码可以调整格式换行,以使得代码更具有可读性
if (() 
    or () 
    or () 
    or ()):
    pass

(二) 循环语句

  • while语句程序计数养成习惯,从0开始

  • break和continue区别,break是跳出整个循环,continue是跳出当次循环

  • 循环遍历 for语句 迭代遍历,提高了列表的访问效率

for 形参变量名 in 列表:
    pass
    break
else:
   	没有通过break退出循环,循环结束后,会执行的代码

注意:

  • 虽然列表也可以存储不同类型数据,单数一般存储相同类型的数据
  • 可以遍历所有非数字型类型的变量:列表、元祖、字典、字符串
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值