【个人笔记】python

Title: Python学习

1 基本用法

输入输出

格式化输出

  • python的格式化输出

    str1 = "num: {}".format(123)
    str1 = "num: {:<44}".format(123)
    str1 = "num: {:^20}".format(123)
    
    • {}.format():占位符、格式控制语句(替换{}的内容);

    • {:<44}{:^20}<表左对齐、>表右对齐,数字是占位符的宽度;

      此处{:<44}表示一个宽度为44的左对齐占位符,{:^20}表示一个宽度为20的居中对齐占位符。

数组

创建

  • 创建指定大小

    # 一维
    a = [1] *10 ;		# 大小位10,初始化全1
    # 二维
    a = [ [1 for i in range(3)] for h in range(4) ]
    # 大小4行3列的二维矩阵
    # a= [ [1,1,1,], [1,1,1,], [1,1,1], [1,1,1] ]
    

添加新元素

  • 先创建空间再添加

    list = 	[1, 2, 3]
    list.append("")		# 不append直接list[4]会报IndexError
    list[4] = 4
    

    错误的方式:直接索引“尾部溢出index”来添加新元素 ❌

列表推导式

  • 英文称呼:List Comprehension

  • 语法B = [a for a in A if a]

    • 含义:对于列表A中的每个元素a,如果a的值为真(非零、非空、非None),则将其添加到新列表中。新列表为B.
    • 优点:比普通for语句在py中运行的快。因为推导式是编译到C语言级别,而普通for语句是解释型。
    • 缺点:更耗内存。

字符串

  • 串拼接

    注意:串和数字拼接,必须手动把数字变量用str()转为字符,否则会报error。

  • 串分割

    list = str1.split(' ')可以化字符串为列表(按间隔符' ')。

文件读写

常规读/写

  • 写文件

    filename = '???'
    with open(filename, 'w') as fp:
        fp.write("...str...")
    

文件指针操作

  • file.seek(offset, 方向用法

    • 细节见此ref:文件操作中file.seek()方法
    • offset的单位:字符数(字节)
    • size = file.tell() 返回文件指针的当前位置,单位-字符数(字节)

    上述单位,不以open("xxx", 'r')还是rb为转移.

    • file.seek()的使用注意事项

      若file是以'r'打开的,则不能随意用.seek(offset数, 0/1/2),因为按字符打开的文本,其文本的编码字节与字符的内容没有一一对应的关系,用.seek()就没法精确按数量移动文件指针(除非调用.tell()函数返回offset的值),用自定义的数值进行.seek()跳转,会出现随机、未知的错误.

      我就出现了使用 file.seek(负数, 2) 的报错:io.UnsupportedOperation: can’t do nonzero end-relative seeks.

      故用.seek()函数时,最好用'rb'的二进制比特流来打开文本。

  • 从文本尾部开始读取,检索关键字

    • 文本必须以二进制流的形式读取、再用seek()函数跳转指针位置、读取比特流后得编码。

    • Demo

      with open(filename, 'rb') as file:
          file.seek(-20000, 2)
          content = file.read()
          str_content = content.decode('utf-8', errors='ignore')
          if 'fatal' in str_content:
              return 1
          else:
              return 0
      
      1. 将文件以只读、二进制的形式打卡

      2. 文件指针跳转到末尾20000个字节处

        utf-8的编码,字符占1,2,4字节,选其倍数即可。

      3. 读取剩下的比特流信息

      4. 编码为utf-8文本

      5. 查看字符串是否在文本中。

  • 在文件开头插入新内容

    注意:跳到开头插入写,默认是覆写。

    • 做梦:提前用file.tell()获得行开头指针的偏移pos,再用readline()读一行,后用file.seek(index)使指针跳回并用file.write(str)实时修改。

    • 现实:文件指针跳转到行头对内容进行修改时,不会自适应进行“插入”或“删减”空间。覆写的字节数不一致时,会使得原文本的尾巴滞留,或覆盖了第二行的文本。

    • 正确方式:直接在python数组中写好后,整体文本重写file中.

2 re库用法

  • 正则表达式 (.*?)是啥意思

    . 是名词,表示“任何字符”

    *是修饰符,表示“任何个数”

    ?是修饰符,表示“尽量少”。

    .*?表示,可以匹配任意长度的词儿,但尽可能少的去匹配。

  • abc def gg.run,要提取gg.rungg ,正则怎么写?

    r"(.*?)\.run"不行,会匹配所有(为啥,我还不知道❓)

    r"(\w+)\.run"可以。✔️

    最终python代码:ans = (re.findall(r"(\w+)\.run", string1))[0]即可,返回的是串;不加[0]返回的是类似json的对象。

  • 如何用re库匹配 ‘abc_123_def’ 或 ‘abc_456_def’ 或 ‘abc_123_defgggg’ 或 ‘abc_456_defgggg’?

    A:r 'abc_[123|456]_def(gggg)*'
    错的!这是java中的正则语法!
    python中, []会匹配其内的所有字符,按“个”进行或选择的。根本不是单词我去。
    而用:ans = re.findall(r 'abc_(123|456)_def(gggg)*', tmp_str) 那么ans会是括号内的值.
    正确答案:ans = re.search(r 'abc_(123|456)_def(gggg)*', tmp_str)

  • re库的 [], ()咋用? 尤其是() ,一会儿是说“提取”功能,一会儿是说“可选匹配)功能…

  • re库的 "" 的作用,在 r'...串...'内添加一个双引号,直接就匹配失效了,为啥??

  • re.match() 是从头开始匹配我去。
    想“从中间匹配都没问题”的话,得用 re.search()

  • re.findall(r'...()...') 得到的是括号里的内容。如果要得到完整的串,得用:
    ans = re.search(r'...()...') ,然后用ans.group(0)进行输出,无法用 ans[0]哈,会error
    若没找到,ans = None

  • findall() 返回的结果,里面的字符串信息,可以用 ans[0] 获取;没有则为""

  • re.search()返回的结果,里面的字符串信息,只能用ans.group(0)获取;没有则为None

3 多进程

  • Popen.poll() 返回值问题

    • 作用:用Popen实现多进程,如:回归测试、VCS仿真。

    • 返回值

      • none:还在运行;

      • 0:正常结束;

      • 其他数字:fatal.

        负数,是 fatal signal错误标志。

    ref: python popen函数讲解

4 工具内容

  • python确定程序运行时间

    import time
    start_t = time.time()
    end_t = time.time()
    print("time: ", ent_t - start_t, " s.")
    
  • python3打印不同颜色的字体

    print("\33[1;36m ...字符串... \033[0m")
    print("\33[1;33m ...字符串... \033[0m")
    print("\33[1;31m ...字符串... \033[0m")
    

5 python 2与3区别

  • print

    • 同:print 皆默认换行;

    • 异:

      python2若不想默认换行,可用 print(), 加个逗号;
      python3若不想默认换行,可用 print("...", end="")

6 other代码参考

  • 自动化make:

    作用:重复make。把每次的log存下来求平均值,最后输出。

     # this is python2
    import os
    import os.path
    import sys
    
    # Paraneters: simulation numbers
    sim_num = 50;
    mode = 0;
    
    
    IN_FILE = "";
    OUT_FILE = "";
    if(mode == 0):
    	IN_FILE = "PR.log";
    	OUT_FILE = "average_PR.log";
    elif(mode == 1):
    	IN_FILE = "SGA.log";
    	OUT_FILE = "average_SGA.log";	
    else:
    	IN_FILE = "cg_record.log";
    	OUT_FILE = "average.log";	
    
    
    print("My python is beginning...");
    log_len = 100 + 1;
    cg_value = [0] * log_len;
    for i in range(sim_num):
    	# run the simulation
    	os.system("make");
    	# read the log and add the CG value to the result list.	
    	PR_log_file = open(IN_FILE,'r');
    	j = 0;
    	try:
    		lines = PR_log_file.readlines()
    		for line in lines:
    			cg_value[j] += float(line.strip());
    			j = j+1;
    			if(j==log_len):
    				break;
    	finally:
    		PR_log_file.close();
    		print( "\n\n\n" + str(i) + "-th sim/" + str(sim_num) + " done!\n\n");	
    
    # show the result
    print("\n\nShow the Average Result:");
    for i in range(log_len):
    	cg_value[i] /= sim_num;
    	print(cg_value[i]);
    
    # write the result
    try:
    	fp = open(OUT_FILE,'w');
    	for value in cg_value:
    		fp.write(str(value) + "\n");
    finally:
    	PR_log_file.close();
    
    
    print(OUT_FILE + " has generated.");
    
    
  • python如何写shell/python如何调用make或makefile

    调用shell的本质就是:os.system("make");

    import os
    import os.path
    import sys
    
    #sys.exit(0);
    #########################################################################################################################
    #
    #	本脚本的作用是:通过配置必要的信息,用python来生成makefile。
     
    (技术支持:www.guimigame.com)
    #	@FILENAME 		运行脚本输出makefile文件名称
    #	@BIN 			生成可运行文件名称
    #	@SUFFIX 		源文件后缀
    #	@ROOTPATH		“根”文件夹路径(脚本工作文件夹的上一层)
    #	@PWD			当前工作文件夹
    #	@WD 			工作文件夹。假设程序有多个工作文件夹请一一用append加上
    #	@BINDIR			可运行文件输出文件夹
    #	@OBJDIR			中间文件输出文件夹
    #	@INCROOTPATH	头文件包括路径的“根路径”,方便INCPATH的编写
    #	@LIBROOTPATH 	包括库的“根”路径。方便LIBS的编写
    #	@INCPATH 		头文件包括路径
    #	@SYSLIBS 		包括的系统库
    #	@LIBS			编译程序须要包括的库
    # 	@CXX			一般填写gcc/g++
    #	@FLAGS			gcc/g++的编译标志
    #
    #########################################################################################################################
    FILENAME 	= 'makefile';
    BIN			= "DatabaseServer";
    SUFFIX 		= ".cpp";
     
    ROOTPATH 	= os.path.dirname(os.path.dirname(os.path.abspath(__file__)));
    PWD 		= os.getcwd();
     
    WD			= [];
    WD.append(PWD);
    WD.append(ROOTPATH + "/common");
     
    BINDIR		= PWD + "/Bin/";
    OBJDIR		= BINDIR + "obj/";
     
    INCROOTPATH	= "-I " + ROOTPATH;
    LIBROOTPATH = "-L " + ROOTPATH;
     
    INCPATH 	= INCROOTPATH + "/common" + " " + INCROOTPATH + "/lib/include";
    SYSLIBS		= " -lmysqlclient -lpthread"
    LIBS		= LIBROOTPATH + "/lib/linux " + "-lTimeManager -lServerConfig -lGameSocket -lCommon -lTinyxml" + SYSLIBS;
    CXX			= "g++";
    FLAGS		= '-g -Wall';
     
    #########################################################################################################################
    #
    #	下面不须要再配置
    #
    #########################################################################################################################
     
    OBJFILE		= '';
    OBJ2SRC		= [];
     
    SOURCES		= "";
     
    def SearchFiles(path):
    	global OBJFILE;
    	global OBJ2SRC;
    	global SOURCES;
    	global SUFFIX;
    	listFile = os.listdir(path);
    	for file in listFile:
    		if os.path.isdir(os.path.join(path, file)):
    			SearchFiles(os.path.join(path, file));
    		elif file.endswith(SUFFIX) > 0:
    			OBJFILE = file;
    			OBJFILE = OBJFILE.replace(SUFFIX,'.o');
    			OBJ2SRC.append([OBJDIR + OBJFILE,path + "/" + file]);
    			SOURCES += path + "/" + file + " ";
     
    for dir in WD:
    	SearchFiles(dir);
     
    if os.path.exists(FILENAME):
        os.remove(FILENAME);
     
    f = open(FILENAME,'w');
     
    f.write("PWD 				= " + PWD + "\n");
    f.write("CXX           		= " + CXX + "\n");
    f.write("INCPATH			= " + INCPATH + "\n");
    f.write("LIBS 				= " + LIBS + "\n");
    f.write("BINDIR				= " + BINDIR +"\n");
    f.write("OBJDIR				= " + OBJDIR + "\n");
    f.write("BIN 				= " + BIN + "\n");
    f.write("SOURCES			= " + SOURCES+ "\n");
    f.write("SOURCEFILES		= $(notdir $(SOURCES))\n");
    f.write("OBJECTS			= $(addprefix $(OBJDIR), $(patsubst %.cpp,%.o,$(SOURCEFILES)))\n");
    f.write("FLAGS				= " + FLAGS + "\n");
    f.write("\n");
     
    f.write("all:makedir $(OBJECTS)\n");
    f.write("	$(CXX) $(FLAGS) $(INCPATH) -o $(BIN) $(OBJECTS) $(LIBS);\n");
    f.write("\n");
     
    f.write("makedir:\n");
    f.write('	$(shell if [ -n "$(OBJDIR)" -a ! -e "$(OBJDIR)" ];then mkdir -p $(OBJDIR); fi)\n');
    f.write('	$(shell if [ -n "$(BINDIR)" -a ! -e "$(BINDIR)" ];then mkdir -p $(BINDIR); fi)\n');
    f.write("\n");	
     
    for val in OBJ2SRC:
    	f.write(val[0] + ":" + val[1] +"\n");
    	f.write("	rm -f $@\n");
    	f.write("	$(CXX) -fpic -c $(INCPATH) $< -o $@\n");
    	f.write("\n");
     
    f.close();
     
    os.system("make");
    os.system("mv " + BIN + " " + BINDIR);
    os.system("cd " + OBJDIR + ";rm -f *.o");
    

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值