Python基础知识

1、概述

1、python中变量可直接使用,无须申明。
2、单行代码结束时可省略分号。 如果将多行代码写在一行,则需要分号分隔。

2、代码注释

python用#号和’’’ ‘’’ 以及 “”" “”" 来注释,如下:

# 这是注释
print("hello world")

'''
这也是注释
多行注释
'''

"""
用三个双引号也可以的
还是多行注释
"""

3、模块的导入语句

在 python 用 import 或者 from…import 来导入相应的模块。
将整个模块(somemodule)导入,格式为: import somemodule

import sys

for i in sys.argv:
    print(i)

从某个模块中导入某个函数,格式为: from somemodule import somefunction
从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc

from sys import argv, path
# 打印命令行参数
for i in argv:
    print(i)

print(path)

将某个模块中的全部函数导入,格式为: from somemodule import *。

如果导入的函数名称有冲突时,需要加入模块前缀。
import后面跟的永远是需要导入的东西,from则说明从哪里导。

4、基本数据类型

python的基本数据类型有6种,Number、String、List、Tuple、Set、Dictionary。
其中不可变数据有 3个,即Number、String、Tuple。
可变的数据类型有3个,即List、Set、Dictionary。
这里的不可变是指其值不可变,其引用还是可以改变的。

4.1、数字

python支持的数字类型有:int,float,bool,complex。

注意:在 Python2 中是没有布尔型的,它用数字 0 表示 False,用 1 表示 True。到 Python3 中,把 True 和
False 定义成关键字了,但它们的值还是 1 和 0,它们可以和数字相加。

a, b, c, d = 100, 5.5, True, 1 + 2j;
print(type(a), type(b), type(c), type(d))
对应输出为
<class 'int'> <class 'float'> <class 'bool'> <class 'complex'>

print(isinstance(a, int))  # True
print(isinstance(a, bool)) # False
print(isinstance(a, float)) # False
print(isinstance(a, complex)) # False

print(5 + 4)
print(5.1 - 8)
print(12 * 13)
print(2 / 4)
print(2 // 4) # 结果取整
print(5 % 3)
print(2 ** 5) # 乘方
对应输出为
9
-2.9000000000000004
156
0.5
0
2
32
4.2、字符串

Python中的字符串用单引号 ’ 或双引号 " 括起来,同时使用反斜杠 \ 转义特殊字符。
python中常用的字符串截取的语法如下:

变量[头下标:尾下标],前闭后开的区间

索引值对应如下(来源于菜鸟教程)
python字符索引图

str = "helloworld"
print(str[0:-1])
print(str[0]) # 注意,返回的是0处索引的值
print(str[2:5]) # 返回的字符中不包括索引为5的字符
print(str[2:]) # 返回索引2后面的全部字符,包括索引2处在内
print(str * 2) # 输出两遍历字符
print(str + "Python") # 连接字符
str2 = "[yes it is]"
print(str2[1:-1]) # 去掉str2中的左右中括号

打印的结果如下:

helloworl
h
llo
lloworld
helloworldhelloworld
helloworldPython
yes it is

String其他方法参见官方文档

4.3、list 列表

List是有序集合类数据结构,可以存储多个元素,也可以嵌套存储集合。List是写在方括号 [] 之间、用逗号分隔开的元素列表,形如[“a”,“b”,“c”]。
List和字符串一样,同样可以被索引和截取,语法如下:

变量[头下标:尾下标]

l = ['hello', 'world', 'java', 'python', 'kotlin']
t = [123, "haha"]
print(l[1]) # 返回单个元素
print(l[1:2]) # 返回的是列表
print(l[1:-1]) 
print(l[1:])
print(l * 2) # 输出两遍列表
print(l + t) # 连接两个列表

# 可通过append向list集合中添加元素。 
l.append("txt")
l.append("doc")
print(l)

打印的结果如下:

world
['world']
['world', 'java', 'python']
['world', 'java', 'python', 'kotlin']
['hello', 'world', 'java', 'python', 'kotlin', 'hello', 'world', 'java', 'python', 'kotlin']
['hello', 'world', 'java', 'python', 'kotlin', 123, 'haha']
['hello', 'world', 'java', 'python', 'kotlin', 'txt', 'doc']

list常用方法见官方文档。

python提供了列表推导器来快速创建一个新的列表。 用法如下:

actions = ['up', 'left', 'down', 'right', 'restart', 'exit']
letter_codes = [ord(ch) for ch in 'WASDRQwasdrq']	# 针对字符串中的每一个字符均会生成对应的ascii码。

# 结果如下
# [87, 65, 83, 68, 82, 81, 119, 97, 115, 100, 114, 113]
# 同时,还可以在列表生成器中加入条件判断语句来过滤一些数据,如下,过滤掉ascii码小于100的数字。 
letter_codes = [ord(ch) for ch in 'WASDRQwasdrq' if ord(ch) > 100]
# 对应的输出为:
# [119, 115, 114, 113]

同时,python也提供了列表生成器来创建列表。 列表生成器不是立即建立完整的列表,而是逐个的生成元素,从而节约内存空间。

colors = ['white', 'black']
a = (c for c in colors) # 如果生成器是某个方法的唯一参数,那么该括号可以省略。
print(a)

# 输出的结果如下:
<generator object <genexpr> at 0x000001AFE6A8CC10>

# 可以看到其类型是生成器,如果要读取内容必须使用迭代。 
4.4、tuple 元组

tuple译为元组。除了元素不可变, 其余特性同list。 不同点在于, tuple是用()来表示的且没有append添加等方法。

c = tuple([1, 2, 3]) # 使用tuple关键字定义时,其参数必需是一个iterable类型
c = ('a', 'xyz', "c", 1234)
print(c)
print(c[1])

特别要注意的是,如果定义只含有一个元素的tuple时,必需要加一个逗号。 因为要区分括号运算。 
c = (1, );	
4.5、set 集合

集合(set)是由一个或数个形态各异的大小整体组成的,构成集合的事物或对象称作元素或是成员。
可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
set集合中不会存储重复的元素,这一点与java类似。

s = set()
s = set([1, 2, 2])
print(s)
相应输出
{1, 2}

set常用方法见官方文档。

4.6、dict 字典

字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合。同Java中的HashMap。
键(key)必须使用不可变类型。在同一个字典中,键(key)必须是唯一的。

# 这两种方式均可申明字典
d = {}
d = dict()
d['a'] = 123
d[123] = 'a'
print(d)
print(d.keys())
print(d.values())
4.7、各种数据类型转换

在这里插入图片描述
上图摘自菜鸟教程。

4、循环语句

python的循环基本与java一样,只是有些细微的差别。 在python中有for、while循环,break是中断最近的一层循环,continue是跳过当次循环,继续下一次循环。
不过,python还提供了for-else语句结构,for 中的语句和普通的没有区别,else 中的语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行,while … else 也是一样。
初看这个结构时,还以为时代码的缩进出现问题了。后来才明白原来这是python提供的一种简洁的语法。这种语法简化了某些场景的代码。
如判断某个数字是不是素数,如下

# 这个示例不是最优的判断素数代码,只是为了说明for-else结构。 
def is_prime(num):
    for i in range(2, num):
        if num % i == 0:
            break
    else:
    	# 如果没有执行上面的break语句,那么for循环结束的时候就会执行else。
    	# 注意else的缩进是和for同级的,不是在循环里面的。else里面的代码只会执行一次。 
        return True

    return False

5、文件及目录操作

5.1 文件读写

打开文件的完整方法如下:

# os是python内置的模块
os.open(path, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
常用的参数为 path 指定文件路径,mode 读写方式,encoding 编码方式(明确指定编码方式能避免出现乱码现象)。 

该方法会返回一个file对象,通过file对象相关方法实现对文件的读写。 常见读写方法有如下几种:

file.read() # 一次性读取所有的字符
file.readline()	# 读取一行(这个还有点疑问,验证一下???)
file.readlines()	# 读取全部行,返回行的列表
file.write()	# 写入字符
file.writelines()	# 将写入的字符当作一行(验证一下???)

在读写文件时,为了更好的管理资源释放,python提供了with语法来自动管理。 使用示例如下:

with open(target_file, "r", encoding="utf-8") as f:
	for line in f:	# 也可以直接通过for遍历文件,遍历的内容是每一行。
		print(line)

# 使用with也可以同时打开多个文件,使用方法如下
with open(target_file, "r", encoding="utf-8") as f, open(target_file2, "r", encoding='utf-8') as f2:
	pass
5.2 目录操作

python内置的os模块提供了大量的文件目录相关的方法。 常用的有os.listdir、os.makedir、os.makedirs(这个方法会递归的创建不存在的目录)、os.remove、os.removedirs(同前面os.makedirs方法,会递归的删除每一级的目录)、os.rename。
在os.path模块中提供了大量的读取文件属性的方法,如判断是文件或目录、文件的更新时间、文件是否存在等等。在使用时可以参考python文档。
常见的操作如下:

# 常见遍历方法
for file in os.listdir(folder):
	full_name = os.path.join(folder, file)
	if os.path.isdir(full_name):
		pass # do something
	else:
		pass # do something


def delete_file(path):
	"""
	删除文件及文件夹
	"""
	if os.path.exists(path):
		print("删除文件: " + path)
		if os.path.isdir(path):
			# 用os.remove删除时如果文件夹是非空那么无法删除成功。故用shutil模块的rmtree方法来删除。 
			shutil.rmtree(path)
		else:
			os.remove(path)

# 同时在os模块中提供了一个os.walk方法可以更高效处理目录和文件。该方法返回的是一个生成器,所以必须在循环中不断遍历它来获得全部的目录或文件。 
# 这篇博客写的很仔细,可以参考。 https://www.cnblogs.com/BlueFire-py/p/8524963.html
# 使用os.walk方法的片段代码如下

# 遍历path路径下的全部文件
def walk_files(path):
	for root, dirs, fs in os.walk(path):
		for f in fs:
			# 返回的是完整的路径名。
			yield os.path.join(root, f)


# 打印路径下的 java 文件
def walk_java_files(path):
	for root, dirs, fs in os.walk(path):
		for f in fs:
			if f.endswith('.java'):
				yield os.path.join(root, f)


# 打印路径下的 图片 文件
def walk_img_files(path):
	for root, dirs, fs in os.walk(path):
		for f in fs:
			if f.endswith('.png') or f.endswith('.jpg'):
				yield os.path.join(root, f)

如果遇到想跳过的文件夹可以采取如下的措施

import os
for root, dir, file in os.walk('./'):
    if os.path.basename(root) == "忽略父文件夹":
        dir[:] = [] # 忽略当前目录下的子目录

# 为什么用dir[:] = [],而不用dir = [] ? dir = []并没有改变原来的列表,而dir[:] = []则是原地修改列表

有了目录和文件操作方法,我们就可以很方便的进行文件读取及修改等操作来简化日常办公。

6、正则表达式

常见的匹配方法如下,(元字符表参见这里。)

# 扫描整个string字符串,pattern为模式字符串,string为待查找字符串,flags是不同类型标记。如是否跨行匹配,是否忽略大小写等。 
# 如果匹配成功,则返回匹配对象(re.MatchObject)。通过整个对象获取匹配的信息。 如果匹配失败,则返回None。该方法最多只匹配一次。 
re.search(pattern, string, flags=0)
# 同search方法,但是匹配的是字符串的开头,如果开头处不匹配则返回None。该方法也最多只匹配一次。
re.match(pattern, string, flags=0) 
# 正则替换,patter是模式字符串,repl是替换后的字符串或者是一个函数(这个函数接受一个参数,该参数是匹配到的对象,并返回处理后的字符串),string是待查找和替换的字符串,count表示替换的最大次数,0表示替换所有匹配。
re.sub(pattern, repl, string, count=0, flags=0)
# 匹配多次,并将结果以集合方式返回,且集合元素类型为匹配对象(re.MatchObject)。 
re.finditer(pattern, string, flags=0)
# 使用正则表达式来分割字符串,maxsplit为最大的分割次数。
re.split(pattern, string[, maxsplit=0, flags=0])

# 如上方法中 flags的取值有如下几种
# re.I 匹配时大小写不敏感
# re.L 本地化识别匹配。(这个暂时没用到,具体用法不是很清楚)
# re.M 多行匹配,影响^和$. 使用该flag时,注意待匹配的字符串中包含了多行文本。 (比如在一行行读取文件内容时,使用此标记可能不会得到正确的跨行匹配结果)
# re.S 使元字符.包括换行在内的所有字符
# re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
# re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。(这个暂时没用到,具体用法不是很清楚)

# 常见使用示例如下:

def split_word(s):
    """
    这个分割单词
    """
    pattern = r"\s+"
    res = re.split(pattern, s)
    print(res)

def split_word_2():
    poem = '锄禾日当午,汗滴禾下土。谁之盘中餐,粒粒皆辛苦。'
    sentence_list = re.split(r'[,。, .]', poem)
    while '' in sentence_list:
        sentence_list.remove('')
    print(sentence_list)  # ['锄禾日当午', '汗滴禾下土', '谁之盘中餐', '粒粒皆辛苦']

def test_sub():
    phone = "18712345239"
    # 替换字符串中的\1与\2是匹配到的分组。在本例中\1指187,\2指239
    result = re.sub('(187).*?(239)', r'\1****\2', phone)
    print(result)


def double_value(matched):
    # matched是被匹配到的对象。 
    old_value = int(matched.group())
    new_value = old_value * 2
    return str(new_value)
    
def test_sub2():
	"""
	将匹配到的数字乘以2
	"""
    s = '23G4HFD567'          
    # 可以在sub中传入函数来处理替换。 这个很实用                 
    result = re.sub(r'\d+', double_value, s)
    print(result)

def modify_config():
    # 坑爹,每次要用复制功能的时候就忘了修改。 干脆在脚本里直接修改。
    target_file = "xxx"
    pattern = 'xxx'
    # 这里.bak文件不存在会自动创建
    with open(target_file, "r", encoding="utf-8") as f1, open("%s.bak" % target_file, "w", encoding="utf-8") as f2:
    	# 这里一次性读取了所有的字符串,也可以根据需要一行行的读取
        all_str = f1.read()
        # 这里的lambda表达式根据模式字符串来修改,并根据需要拼凑出需要替换的字符。
        new_content = re.sub(pattern, lambda x: x.group(1) + "xxx" + x.group(3), all_str, flags=re.S | re.M)
        f2.write(new_content)

	# 删除源文件,并将修改后的.bak文件重命名,这样就相当于在源文件上修改了。 
    os.remove(target_file)
    os.rename("%s.bak" % target_file, target_file)

在使用正则时,还可以将模式字符串编译成一个对象,方便复用。具体参见[这篇博客。](https://www.cnblogs.com/xp1315458571/p/13720333.html) 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值