基础语法学习
果然学完 C++ 后再看其他语言的确有很多的共性,只需要熟悉一下python的独特语法和 C++ 中的差异就可以写出一些小的程序,而写得过程中也再次体会出python代码的精简和灵活;
关键字
所有可用的关键字只要看keyword模块就可以了
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', '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']
编码注释#
在python中如果有需要加中文注释的需求,是需要添加编码注释的。否则就会报错。而python2和python3的编码转换形式还不太一样;
所以通常写程序前需要在最顶部增加编码的声明。其实只要注释里面有coding 和对应的编码就可以了
一般用以下的格式进行声明:
# -*- coding:utf-8 -*-
# coding=utf-8
# coding:utf-8
1、符号的含义
引号
单引号和双引号还有三引号都是使字符串在界面显示。
但是遇到字符里含有’或“时,只要在有单引号(‘)的字符串里用双引号包含起来。有双引号(”)的字符串里用单引号包含起来就可以正常输出了!
单引号
print(‘hello I“m aoy’) # right
print(‘hello I’m aoy’) # error
双引号
print(“hello I‘m aoy”) # right
print(“hello i"m aoy”) # error
三引号
三个引号时则可以将字符串以代码块的形式输出,这个时候使用单引号、双引号都可以正常在字符串里输出了。
print(""“What 's your name My name is 15PB .”"")
2、分支结构 if…else
if语句是最常用的语句了,所以与C++中的使用差距不大,不过条件后要加上冒号:
单个条件
单个条件的判断语法如下:
if 条件1:
条件1符合执行语句
多个条件
多个条件的时候,else if还可以缩写成 elif
if 条件1:
条件1符合执行语句
elif 条件2:
条件2符合执行语句
else:
条件1与条件2都为假时执行语句
3、循环
循环语句还是一样的,不过常用的主要是for和while循环;
for
python中的for循环与传统循环不太一样,是从某处进行调用然后传进临时的变量中,但相比于传统for循环更加灵活;
for 临时变量 in 来源:
实例代码
# 列表循环
for i in ['SQLInject','Weekpass','XSS','UPLOAD','CommandExecute']:
print(i)
# 字符串循环
charstr = "123456"
for i in charstr:
print(i)
while
while循环的语法也差不多,当表达式不成立或是为0的时候就执行下一句,只需要注意缩进就可以,不需要用花括号括起来。
while 表达式:
循环执行语句
实例代码
计算0-9的和
num = 10
i = 0
sum = 0
while (i
sum = sum + i
i= i + 1
print(sum)
4、切片,列表,元组,字典,set
python里很好用的功能就在于处理类似在C++里使用数组,字符串的操作非常简化;
列表和元组概念
列表和元组相当于普通的数组,能够保存任意数量任意类型的python对象,和数组一样,通过从0开始的数字索引访问元素,但是列表和元组可以存储不同类型的对象。
列表元素用中括号([])包裹,元素的个数及元素的值可以改变,元组元素用小括号(())包裹;而元组可以改成是只读的列表,因为列表可以修改单个元素的值,而元组不可以
列表使用
列表常用操作
# 列表定义赋值
>>> list = ['SQLInject','Weekpass','XSS','UPLOAD','CommandExecute']
>>> print(list)
['SQLInject', 'Weekpass', 'XSS', 'UPLOAD', 'CommandExecute']
# 通过索引下表访问列表的元素内容
>>> list[1]
'Weekpass'
# 通过索引下表直接修改某个指定位置的值
>>> list[1] = 'AAAAA'
# 输出列表
>>> list
['SQLInject', 'AAAAA', 'XSS', 'UPLOAD', 'CommandExecute']
>>>
# 二维列表,生成 一个大列表,里面有9个列表,列表里有9个元素
>>> mylist = [ [col for col in range(9)] for row in range(9)]
>>> mylist
[[0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0,
1, 2, 3, 4, 5, 6, 7, 8]]
# 操作二维列表
# 将第三个下标的列表中下标为2的元素值修改为2
>>> mylist[3][2] = 2
>>> mylist
[[0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 2, 0]]
# 浅拷贝
>>> mylist = [[0] *3] * 2]
>>>
# 深拷贝
>>> mylist = [[0 for col in range(4)] for row in range(3) ]
>>>
元组使用
元组常用操作
# 元组定义赋值
>>> aTuple = ('root','administrators','admin','test')
# 输出元祖元素
>>> aTuple
('root', 'administrators', 'admin', 'test')
# 对元组的索引下表是可以的
>>> aTuple[2]
'admin'
# 对元组的索引下表直接赋值是不行的
>>> aTuple[2] = 'HelloWorld'
Traceback (most recent call last):
File "", line 1, in
TypeError: 'tuple' object does not support item assignment
切片使用
python支持使用成对的单引号或双引号,三引号(三个连续的单引号或者双引号)可以用来包含特殊字符,使用索引符([])和切片运算符([:])可以得到字符串。
要注意的是,从前往后的下标是从0开始,从后往前的下标是从-1开始
使用分片列表 实例代码
# 从索引1号从前向后开始列举列表内容
>>> list[1::]
['AAAAA', 'XSS', 'UPLOAD', 'CommandExecute']
# 从索引0号到2号从前往后显示出列表的内容
>>> list[:2:]
['SQLInject', 'AAAAA']
# 从前往后0到9的下标索引,每隔N步取一次值
>>> list[:9:2]
[1, 3, 5, 7, 9]
>>> list[:9:1]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list[:9:3]
[1, 4, 7]
>>> list[:9:4]
[1, 5, 9]
>>> list[:9:5]
[1, 6]
使用分片元组 实例代码
# 从前往后取内容
>>> aTupal = (1,2,3,4,5,6,7,8,9,10)
# 切片操作,从后往前
>>> aTupal[::-1]
(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
>>> aTupal[0::]
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
# 从前往后每次隔2步取一次值;
>>> aTupal[0:9:2]
(1, 3, 5, 7, 9)
# 从后往前取值,前面三位数不要
>>> aTupal[:3:-1]
(10, 9, 8, 7, 6, 5)
字典使用
字典是Python中的映射类型,由键-值(key-value)对构成。几乎所有类型的python对象都可以用作键;值可以是任意类型的Python对象,字典元素用大括号({})包含起来;
# 创建字典
>>> aDict= {'host':'earth'}
# 增加字典
>>> aDict['port'] = 80
# 列出字典
>>> aDict
{'host': 'earth', 'port': 80}
# 循环列出字典元素值
>>> for key in aDict:
... print(key,aDict[key])
...
# 修改字典的内容,根据键名去修改内容
>>> aDict['host'] = 'hello'
>>> aDict
{'host': 'hello', 'port': 80}
# 删除键值,就可以删除键与键值
>>> del aDict['host']
>>> aDict
{'port': 80}
# 删除字典中所有的数据项
>>> aDict.clear()
>>> aDict
{}
5、函数、类
函数的定义
函数跟C语言相比,没有指定特定的类型,需要在参数后用冒号定义;
特点:
1、不需要声明返回类型
2、可以返回多个参数
# 函数名
def function_name([arguments]):
函数执行代码
实例代码
>>> def hello():
... return {'xyz',123,222}
...
>>> HelloReturn = hello()
>>> print(HelloReturn)
{'xyz', 123, 222}
>>>
类的定义
类是面向对象的核心,python中的类与C++也多少有些类似;
实例代码
# 定义一个人类(Human)
class Human(object):
# 类似于构造函数
def __init__(self,Name,Age):
self.Name = Name
self.Age = Age
def Print_Info(self):
# 格式化控制符,当输出多个参数的时候 实际上构成一个字符串表达式。我们可以像一个正常的字符串那样,将它赋值给某个变量。
print('%s | %s '% (self.Name,self.Age))
# 定义一个教师类(Teacher),继承人类(Human)
class Teacher(Human):
def say_Hello(self):
print('%s : hello! I am techer' % self.Name)
# 定义一个学生类(Student),继承人类(Human)
class Student(Human):
def say_Hello(self):
# 当只有一个变量需要以字符串输出时,可以不用括号括起来
print('%s : Hello ! I am student' % self.Name)
objHuman = Human('God',123)
objTea = Teacher('Teacher',456)
objstu = Student('Student',789)
objHuman.Print_Info()
objTea.say_Hello()
objTea.Print_Info()
objstu.say_Hello()
objstu.Print_Info()
运行结果
God | 123
Teacher : hello! I am techer
Teacher | 456
Student : Hello ! I am student
Student | 789
6、文件读写操作
文件输入输出主要使用read、write进行读、写操作;
写入文件
# 写列表到文件中
>>> mylist = [[0 for col in range(4)] for row in range(3) ]
>>> mylist
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
# 打开文件操作
>>> fp = open('D:/test123.txt','w')
# 写入文件操作,返回写入的字节数(byte)
>>> fp.write(str(mylist))
42
# 关闭文件流
>>> fp.close()
>>>
读取文件
方法1:
# 读取文件内容,然后打印出来
>>> fp = open('D:/test123.txt','r')
#42为读取的长度,以字节数(byte)为单位,读取多少字节可以自定义
>>> data = fp.read(42)
>>> print(data)
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
方法2:
filename = 'array_reflection_2D_TM_vertical_normE_center.txt' # txt文件和当前脚本在同一目录下,所以不用写具体路径
with open(filename, 'r') as file_to_read:
while True:
lines = file_to_read.readline() # 整行读取数据
7、目录操作
对目录的操作通过os模板实现
import os
# 创建一个目录
os.mkdir('D:/hello/')
# 删除一个目录,目录非空时无法删除
os.rmdir('D:/hello')
# 查看当前目录的绝对路径
>>> import os
>>> strpath = os.path.abspath('.')
>>> strpath
'C:\\Users\\Windows32'
# 目录拼接,然后在创建目录
>>> strNewPath = os.path.join('D:/','Testdir')
>>> strNewPath
'D:/Testdir'
>>> os.mkdir(strNewPath)
>>>
# 拆分路径,将其才分为路径+文件名
>>> strSubPath,strFileName = os.path.split('D:/Testdir/file.txt');
>>> print(strSubPath,strFileName)
D:/Testdir file.txt
编码转换
在玩CTF时会遇到很多编码转换的题目,使用高级语言写完估计比赛也就结束了,python可以对这些编码做很好的处理。
在python2版本中代码默认编码为ascll,python3版本中默认编码为utf-8,所以python2版本经常出现解析中文成乱码的问题。而python3可以正常解析中文,无需指定编码。
这里列举常用编码的转换方式:
ascii码转换
将ASCII字符转换为对应的数值即‘a’–>65,使用ord函数,ord(‘a’)
>>> ord('a')
97
>>>
反之,使用chr函数,将数值转换为对应的ASCII字符,chr(65)
>>> chr(102)
'f'
字符串:如果遇到连续的字符串只需要加入循环语句就可以翻译了
for i in [97,98,99,104,100,102,101,96,64]:
print chr(i)
HEX转换
python2用法
在python2中指定编码为hex就可以进行转换
>>> print "7468655f666c61675f6462".decode("hex")
the_flag_db
>>>
python3用法
python3转换hex的方式与python2略有不同
>>> print binascii.unhexlify('7061756c')
paul
python3自写16进制转换ascii码函数
以下代码的作用做了三个步骤,将字符串转化为ascii码
1、第4行代码16进制按位与运算取出单个字符(1个字符转换2进制占据有8位),然后chr()函数转换成ascii码,写到数组里去;
2、第5行代码把取过的字符去掉,因为是与&运算,除以最后一位,向右位移8位,去掉已经转换后压入数组的字符
3、第六行代码因为是从最后一位逐个取字符压入数组的,所以会有一个反转排序的操作
def convert_hex_to_ascii(h):
chars_in_reverse = []
while h != 0x0:
chars_in_reverse.append(chr(h & 0xFF))
h = h >> 8
chars_in_reverse.reverse()
return ''.join(chars_in_reverse)
print(convert_hex_to_ascii(0x6162))
base64解码python -c "import base64; print base64.b64decode('bGlqaWVqaWVAcWl5aS5jb20=')"
unicode解码import unicodedata
def unicode2ascii(data):
return unicodedata.normalize('NFKD', data).encode('ascii', 'ignore')
data = u'\u5927\u5bb6\u597d\uff0c\u6211\u662f\u0040\u65e0\u6240\u4e0d\u80fd\u7684\u9b42\u5927\u4eba\uff01\u8bdd\u8bf4\u5fae\u535a\u7c89\u4e1d\u8fc7\u767e\u771f\u7684\u597d\u96be\u3002\u3002\u0077\u0063\u0074\u0066\u007b\u006d\u006f\u0072\u0065\u006d\u006f\u0072\u0065\u005f\u0077\u0065\u0069\u0062\u006f\u005f\u0066\u0061\u006e\u0073\u007d'
print unicode2ascii(data)