python 学习


这篇博客会经常性地持续更新,记录使用python过程中的一些琐碎技能

类成员变量和对象成员变量

class A():
	name = "caixukun"
	
	def __init__(self):
		self.name = "changtiaorap"

if __name__ == "__main__":
	a = A()
	print(A.name)
	print(a.name)

输出

caixukun
changtiaorap

这说明:

  • 在方法外定义的变量属于类成员变量,不从属于任何一个对象实例
  • 在构造方法内通过self.构造的变量属于对象成员变量
  • 如果对象成员变量和类成员变量同名,则通过对象实例访问的变量是对象成员变量,否则是类成员变量。

在python中,基础类型没有枚举。模仿枚举的方式往往采用类成员变量模拟:

class CityPopulation():
	shenzhen = 818.11
	shanghai = 972.69
	beijing = 794.3
	chengdu = 437
	wenzhou = 297
	xiamen = 221.02

python的伪多线程

python的多线程一直是一个令人诟病的问题,原因就是因为python的多线程是一个伪多线程,意思是说,尽管是多线程在运行,实际上仍然是单核CPU上的时间片轮询。无论你使用了多少多线程,python始终只能利用一个CPU核。造成这种现象的原因在于CPython解释器中大名鼎鼎的全局锁(GIL)(当然,其他python解释器也可能会有)。

在上世纪,CPython解释器诞生的年代,并没有期待往后的计算机性能会有如此大的进步。GIL的出现主要是为了解决线程安全问题。然而。在如今,多线程的编写已经司空见惯,但是python的GIL阻止了python使用者去编写一个性能良好的程序。

其实在上世纪末,1999年,有人创建了一个python分支去专门试图移除GIL。下面是python创始人 Guido Van Rossum的一段话:

This has been tried before, with disappointing results, which is why I’m reluctant to put much effort into it myself. In 1999 Greg Stein (with Mark Hammond?) produced a fork of Python (1.5 I believe) that removed the GIL, replacing it with fine-grained locks on all mutable data structures. He also submitted patches that removed many of the reliances on global mutable data structures, which I accepted. However, after benchmarking, it was shown that even on the platform with the fastest locking primitive (Windows at the time) it slowed down single-threaded execution nearly two-fold, meaning that on two CPUs, you could get just a little more work done without the GIL than on a single CPU with the GIL. This wasn’t enough, and Greg’s patch disappeared into oblivion. (See Greg’s writeup on the performance.)

这次的尝试以惨败告终,移除GIL后的性能比单线程应用慢了近两倍。于是,他干脆直接说不必花太大的精力在GIL上。而面对不断被询问的多线程问题,python的专家们也精心准备了一个答案:

不要使用多线程,用多进程代替

然而,进程的创建和进程间通信使得在很多场合性能不如多线程。这意味着python从一开始就与高性能三字无缘。

在python 4.0的预计推出的新特性列表中,有这么一条:

The GIL has been removed

是不是非常地开心呢?

然而,这一条的下面一条,是这样的:

Just kidding! Instead we’ve been focusing all our effort on making it easier to juggle multiple interpreter data-structures within a single thread. No, no, you can thank us later!

这种无奈的玩笑,大概只有python的维护者们真正懂。python 4.0 预计推出的新特性链接点这里

在未来,Rust会因为安全而火起来,而golang会因为高性能变得更火。

python之读取Excel

读取Excel需要使用模块xlrd,这个模块的安装,直接pip install xlrd就好了。
读取一个Excel数据需要两个数据,一个是Excel表的路径 ,一个是sheet名称。下面书写一个接口,接受这两个数据,将对应的Excel中对应的Sheet表的所有数据读取到一张二维list中。

def read_excel(xls_path, sheet_name):
	wb = xlrd.open_workbook(xls_path) # 打开Excel表格
    sheet = wb.sheet_by_name(sheet_name) # 打开其中一张Sheet
    cols = sheet.ncols # 列
    rows = sheet.nrows # 行

    sheet_list = []
    
    for i in range(rows): # 逐行读取
        row_list = []
        for j in range(cols):
            row_list.append(sheet.cell(i, j).value)
        sheet_list.append(row_list)
    
    return sheet_list

python之写入Excel

写入Excel需要导入xlsxwriter包,直接使用pip install xlsxwriter进行安装。

关于这个包的使用,强烈建议阅读官方文档。这里我将简略展示我用到的关于xlsxwriter的部分功能,其中包括:

  • 打开和关闭表格
  • 写入数据
  • 插入图表
  1. 简单的插入数据
import xlsxwriter

wb = xlsxwriter.Workbook('NewExcel.xlsx') # 打开表格
sheet = wb.add_worksheet('Sheet1') # 打开工作表

# 写入一行或一列数据
data = [1,2,3]
data2 = (4,5,6)
sheet.write_column('A11', data) # data 需要是可迭代对象
sheet.write_row('B11', data2)

sheet.set_column('A:J', 20) # 设置A到J所在列宽度为20

# 为单元格设置格式
wb_format = wb.add_format({
 	'bold': True, # 加粗
 	'border': 2, # 边框
    'align': 'center', # 水平对齐
    'valign': 'vcenter', # 垂直对齐
    'fg_color': '#6D92f6' # 颜色
})

# 带格式的写入
sheet.write('A3', '服务器版本', wb_format)
# 合并单元格
sheet.merge_range('A1:J2', '总体情况', wb_format)

wb.close() # 必须有这一步,而且是直到这一步,上面的所有操作才会执行
  1. 插入图表
import xlsxwriter

# 打开表格
wb = xlsxwriter.Workbook('2807年 地球人口统计.xlsx') # 打开表格
sheet = wb.add_worksheet('第一次普查') # 打开工作表

# 定义数据
category = ['男人', '女人','中性人','外星人']
value = [23.45, 23.03, 12.71, 45.34] # 单位 亿

# 写入数据
sheet.write_column('A1', category)
sheet.write_column('B1', value)

# 定义图表
chart = wb.add_chart({'type': 'pie'}) # 这里pie表示绘制饼状图,还有更多的类型
chart.add_series({
	'categories': '=第一次普查!$A$1:$A$4',
    'values': '=第一次普查!$B$1:$B$4',
	'data_labels': {'category': True, 'percentage': True, 'leader_lines': True} # 分别显示:类别名, 百分比, 引导线
})
chart.set_title({'name': '第一次普查结果'})
chart.set_size({'x_scale': 2, 'y_scale': 2}) # 这里表示以默认大小的两倍显示
chart.set_style(10)

# 插入图表
sheet.insert_chart('C1', chart)

wb.close() # 必须有这一步,而且是直到这一步,上面的所有操作才会执行

在这里插入图片描述

Mysql的安装和导入csv文件

当我再次操起Mysql的时候,Mysql已经被Oracle收购了。所以现在想要下载Mysql,首先得上Oracle官网。然而,自从不知道什么时候开始,下载Java sdk也需要登录Oracle之后,我对Oracle的官网总是有种莫名的恐惧。尽管全球为开源社区贡献榜单中Oracle公司名列前茅,但是大家似乎都在担心Mysql因此变得不开源。

另外这个问题放在这儿,是考虑以后可能会使用python操作数据库的需求。与其再建一个“数据库学习”博客,不如就写在这儿。

社区版的下载链接在

在这里插入图片描述

下载好msi之后,一路安装,不是点next,就是点Excute,或者finish。总而言之,对于新手来说,没有什么值得配置的地方。

那么这次的问题在于,MySql导入带有中文的CSV会有各种问题。

  • 中文编码问题
  • 权限问题
  • 头部去除问题

这些问题对于老手而言很简单,然而对于我这样的新手,可是花了不小功夫去查资料解决。

首先假设我们已经有了一个名为DB的数据库和名为my_data的表。然后按照网上的教程,在Mysql workbench左侧右键表,点击table data import wizard,打开数据导入向导页面。然后选择文件路径,开始导入。然后出错了。噢,编码问题。再按照网上套路,打开记事本,另存csv文件,选择编码utf-8。再按流程来一遍,还是出错。显然utf-8格式压根儿不对,因为中文编码基本上就是gb2312。可惜Mysql不提供这种编码方式的导入。然后网上又推荐使用navicat for mysql导入csv。于是我就为了导入一个中文编码的文件,还要费尽周章下载一个额外的软件,还是付费的!

解决方法使用load data infile语句。用sql语句导入,同时指定导入时的编码。

load data infile 'D:/files/data.csv'
into table my_data character set gb2312 
fields terminated by ',' optionally enclosed by '"' escaped by '"' lines terminated by '\r\n';

这里要注意文件名的路径分隔符建议用/,如果你在windows底下用\,一定要记得用\\

到这里呢,还报错,说数据库运行在secure-file-priv模式下,这个命令不允许执行。原因在于,MySql的配置里有一个secure-file-priv。它的值如果不为空(默认是一个路径),则只能从这个路径下读取文件。

解决方法是把它改为空值。配置文件是C:\ProgramData\MySQL\MySQL Server 8.0\my.ini。找到这一项,然后=""就好了。

现在重启电脑(或者如果你会重启Mysql服务的话),运行脚本。还报错,不过显然文件可以读取了。错误显示读取的数据跟表定义的数据格式不符。原因在于,csv文件通常有开头一行不属于“数据”范畴,它是这些数据的“headers”,用来定义每一列数据的具体含义。或者有时候有更多行。但是Mysql读取的时候,是从第一行读取,不会帮你识别和忽略。解决办法是在sql语句后面加一句ignore 1 lines,用来忽略第一行。

load data infile 'D:/files/data.csv'
into table my_data character set gb2312 
fields terminated by ',' optionally enclosed by '"' escaped by '"' lines terminated by '\r\n' ignore 1 lines;

python 之 json 模块

import json

d = {"name":"qtc", "age":3, "tall":1.66, "girl_friend":{"name":"fanbingbing", "age":40, "tall":1.8}}
ret = json.dumps(d) # 将字典转化成字符串

将json字符串格式化打印:

j = json.dumps(json.loads(msg), indent=4)

python 之文件解压缩

import zipfile

# 解压文件
zfile = zipfile.ZipFile("origin_file.zip", "r")
zfile.extractall("./")
zfile.close()

# 压缩文件
files = os.listdir("./logs")
with zipfile.ZipFile("myzip.zip", mode="w", compression=zipfile.ZIP_LZMA, allowZip64=True) as f:
	for file in files:
		f.write(f"./logs/{file}", arcname=file)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值