9.文件操作

系统命令
文件操作
序列化
JSON

1.系统命令

import os

print(os.name)  # 操作系统类型
print(os.environ.get('CLASSPATH'))  # 获取系统中CLASSPATH环境变量的值
print(os.path.abspath('.'))  # 当前目录的绝对路径

输出结果:
nt
.;C:\Program Files\Java\jdk1.8.0_51\lib\dt.jar;C:\Program Files\Java\jdk1.8.0_51\lib\tools.jar;
J:\Python\code\PythonTest\test9

nt说明是windows系统,如果是Linux、Unix、或Mac,就会是posix。

2.文件操作

import os


os.mkdir(os.path.join('/Python', 'TestDir'))  # 在根目录的Python目录下创建TestDir目录
os.rmdir(os.path.join('/Python', 'TestDir'))  # 删除根目录下的Python目录下的TestDir目录

如果文件已经存在会报FileExistsError异常:

Traceback (most recent call last):
  File "J:/Python/code/PythonTest/test9/test9_1.py", line 7, in <module>
    os.mkdir(os.path.join('/Python', 'TestDir'))  # 在根目录的Python目录下创建TestDir目录
FileExistsError: [WinError 183] 当文件已存在时,无法创建该文件。: '/Python\\TestDir'

os.path.join是把拼接路径,相当于java里的FIle.sepreter,当把两个路径拼接时,如果直接用一个字符串拼接,会有系统差异,在Linux、Unix和mac中是path1/path2,在windows中是path1\path2,分隔符不一样,如果用os.path.join就会自动匹配当前系统的分隔符。
同理拆分路径时也要用对应的api去分:

print(os.path.split('/Python/TestDir'))  # 拆分路径
输出结果:
('/Python', 'TestDir')

得到文件后缀名:

print(os.path.splitext('/Python/TestDir/test9_1.py')) 
输出结果:
('/Python/TestDir/test9_1', '.py')

拆分合并这些操作实际上操作的是一个字符串,和文件无直接关系,所以文件和目录并不一定存在。

不过要修改某个路径下的文件名这种操作就需要文件存在了:

os.rename('/Python/TestDir/test9_1.py', '/Python/TestDir/test9_2.py')

列出某个目录下的文件夹:

print([x for x in os.listdir('/Python') if os.path.isdir(os.path.join('/Python', x))])
输出结果:
['code', 'PyCharm 2017.2.3', 'TestDir']

列出当前目录下所有.py文件:

print([f for f in os.listdir('.') if os.path.isfile(f) and os.path.splitext(f)[1] == '.py'])
输出结果:
['test9_1.py', '__init__.py']

3.序列化
程序运行时的对象或变量都是在内存中,例如一个Person对象,一个dict,如果想把这些数据存到磁盘里或通过网络传输,就要先进行序列化,就像java的serialization ,在python中叫pickling,把序列化后存储的内容重新加载进内存要反序列化,python提供了pickle模块来实现序列化:

import pickle

d = dict(name='tom', age=20)
dumps = pickle.dumps(d)  # 序列化
print(dumps)
with open('dump.txt', 'wb') as f:
    pickle.dump(d, f)  # 将序列化的内容保存到文件
输出结果:
b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x04\x00\x00\x00nameq\x02X\x03\x00\x00\x00tomq\x03u.'

反序列化:

with open('dump.txt', 'rb') as f:
    d = pickle.load(f)  # 从文件中读取内容并反序列化成对象
    print(d, d['name'], d['age'])
输出结果:
{'age': 20, 'name': 'tom'} tom 20

4.JSON

JSON类型 Python类型
{} dict
[] list
“string” str
123.456 int或float
true/false True/False
null None

json.dumps(obj)可以把一个对象变成一个Json格式的str:

import json

d = dict(name='tom', age=20)
dumps = json.dumps(d)  # 序列化
print(dumps)
---
{"age": 20, "name": "tom"}

json.load(file)或json.loads(str)方法可以把json反序列化为一个python对象,loads用来反序列化一个str,load用来直接反序列化一个文件里的内容:

loads = json.loads(dumps) #反序列化成对象
print(loads)
print(type(loads))
---
{'age': 20, 'name': 'tom'}
<class 'dict'>

因为JSON标准规定JSON编码用的是UTF-8,所以在Python中互转时不用指定编码。

自定义对象json序列化

Python中的dict可以直接序列化成标准json串,也可以把标准json串反序列化成一个dict,但是在开发中,只用dict肯定是不够的,例如定义一个Persion类,如果直接序列化就会报异常,这是因为这个Person对象不是一个可序列化的对象

Traceback (most recent call last):
  File "J:/Python/code/PythonTest/test9/test9_4.py", line 19, in <module>
    print(json.dumps(p))
  File "C:\Users\aisl\AppData\Local\Programs\Python\Python35\lib\json\__init__.py", line 230, in dumps
    return _default_encoder.encode(obj)
  File "C:\Users\aisl\AppData\Local\Programs\Python\Python35\lib\json\encoder.py", line 198, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Users\aisl\AppData\Local\Programs\Python\Python35\lib\json\encoder.py", line 256, in iterencode
    return _iterencode(o, 0)
  File "C:\Users\aisl\AppData\Local\Programs\Python\Python35\lib\json\encoder.py", line 179, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <__main__.Person object at 0x00000000006BD9E8> is not JSON serializable

这时可以通过在json.dumps()方法的可先参数上配置一个自定义的方法,用来指定该对象的序列化方式:

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age


def person2json(person):
    return {
        'name': person.name,
        'age': person.age
    }


p = Person('Mary', 20)
dumps = json.dumps(p, default=person2json)
print(dumps,type(dumps))
---
{"name": "Mary", "age": 20} <class 'str'>

同理,反序列化也要自定义一个方法来指定反序列化的方式:

def json2person(d):
    return Person(d['name'], d['age'])


p1 = json.loads(dumps, object_hook=json2person)
print(p1, p1.name)
---
<__main__.Person object at 0x0000000000B5C710> Mary

每写一个对象序列化时都要定义一个default比较麻烦,可以用下面的方法把任意对象的实例变为dict:

s = Student('Mary', 20)
json_dumps = json.dumps(s, default=lambda obj: obj.__dict__)
print(json_dumps, type(json_dumps))
---
{"name": "Mary", "age": 20} <class 'str'>

猜你喜欢

转载自blog.csdn.net/aislli/article/details/81169815