博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python基础
阅读量:3786 次
发布时间:2019-05-22

本文共 19455 字,大约阅读时间需要 64 分钟。

目录

python基础

特殊用法

# 转移字符 ‘\’, 其中\t 表示制表符 \n表示换行print('I\'m ok')# Python使用r''表示‘’内部的字符串默认不允许转义print(r'\n')# 字符串中的多行内容''' '''print('''line1line2''')# -*- coding: utf-8 -*-  指定当前的编码方式

字符串和编码

ASCII编码1个字节,Unicode编码2个字节,UTF-8编码可变长编码,UTF-8根据不通的数字大小编码成1-6个字节,常用的应为被编码成一个字节,汉字通常编码为3个字节,生僻字被编码为4-6个字符。

在机器内存中,统一使用Unicode编码,当需要保存到硬盘或者传输的时候,就会转化为UTF-8编码

# Python字符串# 使用ord()获取字符的整数表示,使用chr()函数吧编码转化为字符print(ord('中'))print(chr(20013))#使用16进制表示print('\u4e2d')
20013中中
#python 字符串类型是str,在内存中以Unicode表示,在网络传输和保存到磁盘时,需要将str变为字节为单位的bytesx = b'abc'print(x)print('adc'.encode('ascii'))
b'abc'b'adc'
#如果从网络或者磁盘上读取字节流,那个需要将bytes转化为str( b'\xe4\xb8\xad\xe6\x96\x87').decode('utf-8')
'中文'
# 计算str包含多少个字符串,len()函数,如果转化为bytes,len()函数就计算字节数print(len('abc'))print(len('中文'))print(len(('中文').encode('utf-8')))
326
# 格式化输出字符串, 在字符串内部,%s表示用字符串替换,%d表示用整数替换,%f表示浮点数, %x 表示十六进制print('hello, %s' % ('world'))# 对于字符串中的%号,使用%%表示一个%print('hello, %%')# 另一种方法是使用format()方法格式化,参数依次替换字符串内的占位符{0}、{1}……
hello, worldhello, %%

list和tuple

# list 是一个可变的有序列表classmates = ["ming","zhao","li"]# 使用append往末尾追加数字classmates.append("sun")# 使用insert插入数据classmates.insert(1,'jack')print(classmates)print(classmates[0])print(classmates[-1])print(classmates[:-1])print(classmates[:-2])# 删除list末尾的元素classmates.pop()print(classmates)#删除指定位置的元素classmates.pop(0)print(classmates)# 替换指定位置的元素classmates[0] = 1print(classmates)
['ming', 'jack', 'zhao', 'li', 'sun']mingsun['ming', 'jack', 'zhao', 'li']['ming', 'jack', 'zhao']['ming', 'jack', 'zhao', 'li']['jack', 'zhao', 'li'][1, 'zhao', 'li']
#tuple 元组# tuple和list非常类似,但是tuple一旦初始化,就不能修改了classmates = ("1","2","3")print(classmates)#当只有一个元素的tuple时,会加一个逗号classa = (1,)# 当是有一个括号是,也是tuple类型a = ()
('1', '2', '3')
d = (3,)e = (4,5,6)a = ()print(d,e,a)
(3,) (4, 5, 6) ()
### 条件判断print(range(5))print(list(range(5)))
range(0, 5)[0, 1, 2, 3, 4]
# 循环# 计算1-100的和sum = 0for i in range(101):    sum = sum + iprint(sum)sum = 0n=0while n<=100:    sum = sum + n    n = n+1print(sum)
50505050

dic和set

# dictd = {
'Michael': 95, 'Bob': 75, 'Tracy': 85}# 从dict中获取,这种方式在获取时,如果key不存在,则抛出异常print(d['Michael'])# 使用get时,如果不存在,则返回None,可以通过在后面添加默认值的方式,初始化print(d.get("666","777"))# 删除某key时,可以通过pop(key)#dict 和list相比# dict查询和插入的速度极快,不会随着key的增加而减慢速度# 占用大量的内存,内存浪费多
95777
# set 创建set,需要提供一个list输入作为集合,s = set([1,2,3])print(s)# 添加元素s.add(4)# 删除元素s.remove(1)print(s)
{1, 2, 3}{2, 3, 4}

函数

调用函数

# 查看函数信息help(abs)
Help on built-in function abs in module builtins:abs(x, /)    Return the absolute value of the argument.
# 绝对值函数print(abs(-100))# 最大值函数print(max(1,2))#数据类型转换print(int('132'))print(bool(' '))print(bool(''))#将整数转化为16进制print(hex(16))
1002132TrueFalse0x10

定义函数

# 空函数def nop():    pass# 定义参数类型def my_abs(x):    if not isinstance(x,(int,float)):        raise TypeError("bad oprand type")    if x > 0:        return x    else:        return -xprint(my_abs(-2))import math# 返回多个值,实际上,Python返回的仍为单一值,tupledef move(x, y, step, angle=0):    nx = x + math.cos(angle)*step    ny = y + math.sin(angle)*step    return nx, nyprint(move(1,2,5,30))# 开根号print(math.sqrt(4))
2(1.7712572494379202, -2.940158120464309)2.0

函数的参数

函数的参数除了必选的参数外,还可以使用默认参数、可变参数、关键字参数

  • *args是可变参数,args接收的是一个tuple;

  • **kw是关键字参数,kw接收的是一个dict。

def power(x, n):    s = 1    while n > 0:        n = n - 1        s = s * x    return sprint(power(2, 2))# 默认参数 ## 注意事项。必填参数在前,默认参数在后# 可变参数,这些可变参数在函数调用时,自动组装成一个tupledef calc(*numbers):    sum = 0    for i in numbers:        sum += i    return sumprint(calc(1,2))print(calc(1))# 对于可变参数的函数,可以使用*num将元组或者list转化为可变参数,传入函数中print(calc(*[1,2]))# 关键词参数, 关键词参数在函数的内部自动组装为一个dic **表示关键词参数def person(name, age, **kw):    print("name",name, "age", age, 'other', kw)person("tom", 30)person('Adam', 45, gender='M', job='Engineer')other = {
'city':'beijing', "job":'engineer'}person('Adam', 45,**other)# 命名关键参数,关键字参数**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数def person(name, age, *, city, job): print(name, age, city, job)person('Jack', 24, city='Beijing', job='Engineer')#如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:def person(name, age, *arg, city, job): print(name, age, city, job)person('Jack', 24, 32, city='Beijing', job='Engineer')# 参数组合## 必选参数、默认参数, 可变参数, 命名关键词参数, 关键词参数
4313name tom age 30 other {}name Adam age 45 other {'gender': 'M', 'job': 'Engineer'}name Adam age 45 other {'city': 'beijing', 'job': 'engineer'}Jack 24 Beijing EngineerJack 24 Beijing Engineer

递归函数

  • 使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试fact(1000):
# n阶乘def fact(n):    if n ==1:        return 1    else:        return fact(n-1)*nprint(fact(5))#尾递归# 尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。#这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。def fact(n):    return fact_iter(n, 1)def fact_iter(num, product):    if num == 1:        return product    return fact_iter(num - 1, num * product)
120

高级特性

切片

li = list(range(100))# 取前10个数print(li[0:10])print(li[:10])#取后十个数print(li[-10:])# 前10个数,每两个取一个print(li[:10:2])# 复制一个listprint(li[:])# tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:# 字符串'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:# 。Python没有针对字符串的截取函数,只需要切片一个操作就可以完成
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][0, 1, 2, 3, 4, 5, 6, 7, 8, 9][90, 91, 92, 93, 94, 95, 96, 97, 98, 99][0, 2, 4, 6, 8]

迭代

# 通过for循环来遍历这个list或tuple# 只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代d = {
'a':1, 'b':2}for key in d: print(key)# 迭代valuefor value in d.values(): print(value)# 同时迭代key valuefor k, v in d.items(): print(k,v)
ab12a 1b 2
# 判断一个对象是否为可迭代对象# 通过collections模块的Iterable类型判断from collections import Iterableisinstance('abc', Iterable)
d:\software\python\python37\lib\site-packages\ipykernel_launcher.py:3: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working  This is separate from the ipykernel package so we can avoid doing imports untilTrue
# 对list实现类似Java那样的下标循环,Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身for i, value in enumerate([1,2,3]):    print(i, value)
0 11 22 3

列表生成

# 创建列表[x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]

生成器

生成器中包含了算法,在数据生成时,一边循环一边计算

# 把列表生成式的[] 改为(), 就创建了一个generatorL = [x*x for x in range(2)]print(L)g = (x*x for x in range(2))print(g)# generator保存的是算法,每次调用next,就计算出g的下一个元素的值,没有更多元素时,抛出stopIteration的错误# print(next(g),next(g))# 通常使用for循环for n in g:    print(n)
[0, 1]
at 0x000002A67A63A4F8>01
# 利用yeild函数实现生成器def fib(max):    n, a, b = 0, 0, 1    while n < max:        print(b)        b = a + b        a, b = b, a+b  # t = (b, a + b) # t是一个tuple, a = t[0]  b = t[1]        n = n + 1    return "done"print(fib(3))def fib(max):    n, a, b = 0, 0, 1    while n < max:        yield b        b = a + b        a, b = b, a+b  # t = (b, a + b) # t是一个tuple, a = t[0]  b = t[1]        n = n + 1    return "done"print(fib(3))
113done
# 函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,# 在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行def odd():    print('step 1')    yield 1    print('step 2')    yield(3)    print('step 3')    yield(5)for i in odd():    print(i)
step 11step 23step 35
# 如果想拿到返回值,必须捕获stopIteration错误,返回值包含在stopIteration的value中。g = fib(3)while True:    try:        print(next(g))    except StopIteration as e:        print("Generator return value:", e.value)        breakprint("执行完成")
113Generator return value: done执行完成

迭代器

可以用于for循环的数据类型一类是数据集合 list tuple set dic str ,一类是generator,成为可迭代对象

可以使用被next()函数调用,并返回下一个值的对象成为迭代器
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

# 使用isinstance()判断一个对象是否是iterablefrom collections import Iterableisinstance([],Iterable)
True
# 使用isinstance()判断一个对象是否是iteratorfrom collections import Iteratorprint(isinstance([],Iterator))# 生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。# 将list dict str 变为iteratorprint(isinstance(iter([]), Iterator))
FalseTrue

函数式编程

map/reduce

# map() 第一个参数即函数本身,第二个参数是一个列表,生成的是一个迭代器 Iterator,是一个惰性序列L = map(str, [1,2,3])print(L)print(list(L))L = map(int, '123456')# 将数字转化为列表的形式print(list(L))
['1', '2', '3'][1, 2, 3, 4, 5, 6]
# reduce 把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,# reduce会继续把结果和序列的下一个元素做累积运算# reduce(f,[1,2,3])from functools import reducedef add(x, y):    return x + yreduce(add, list(range(101)))
5050

filter

# filter   过滤序列,也是接收一个函数和一个序列(顾虑,只保留符合条件的数据)# filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素def is_odd(n):    return n % 2 == 1list(filter(is_odd, [1,2,3,4,5]))
[1, 3, 5]
# 使用filter求素数# 构建从三开始的奇数序列def _odd_iter():    i = 3    while True:        yield(i)        i += 2# 定义一个筛选器def not_divisible(n):    return lambda x:x%n>0# 定义一个生成器,不断返回下一个素数def primes():    yield e    it = _odd_iter()    while True:        n = next(it)        yield n        it = filter(not_divisible(n), it)for n in primes():

sorted

sorted 函数Python内置

# 对list进行排序sorted([36,-5,16])
[5, 16, 36]
# 接收key函数,实现自定义的排序sorted([36,-25,16],key=abs)
[16, -25, 36]
# 对字符串排序,是按照ASCII的大小比较的sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']
# 忽略大小的排序sorted(['bob', 'about', 'Zoo', 'Credit'],key=str.lower)
['about', 'bob', 'Credit', 'Zoo']
# 实现反向排序sorted(['bob', 'about', 'Zoo', 'Credit'],key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']

返回函数

相关的参数和变量都包含在返回函数中,这种称为“闭包”

def lazy_sum(*args):    def sum():        ax = 0        for n in args:            ax = ax + n        return ax    return sum

匿名函数

关键词lambda 表示匿名函数,冒号前面x表示函数参数

lambda x: x * x 冒号前面表示匿名函数的参数,冒号后面表示 表达式
匿名函数只有一个表达式,不用写return

list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
# 匿名函数也可以赋值给变量f = lambda x: x * xf(5)
25

装饰器

代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator),比如增加日志,有点类似于切面编程

def log(func):    def wrapper(*args, **kw):        print('call %s()' %func.__name__)        return func(*args, **kw)    return wrapper@logdef now():    print("2019-10-10")now()print(now.__name__)
call now()2019-10-10wrapper
# 三层嵌套的now函数def log(text):    def decorator(func):        def wrapper(*args, **kw):            print('%s %s():' % (text, func.__name__))            return func(*args, **kw)        return wrapper    return decorator@log("execute")def now():    print("2019-10-10")now()print(now.__name__)
execute now():2019-10-10wrapper
## 解决 now.__name__函数名字改变,通过Python内置的functools.wrapsimport functoolsdef log(func):    @functools.wraps(func)    def wrapper(*args, **kw):        print('call %s():' % func.__name__)        return func(*args, **kw)    return wrapperdef log(text):    def decorator(func):        @functools.wraps(func)        def wrapper(*args, **kw):            print('%s %s():' % (text, func.__name__))            return func(*args, **kw)        return wrapper    return decorator

偏函数

functools.partial就是帮助我们创建一个偏函数的

当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

import functoolsdef int2(x, base=2):    return int(x, base)# 使用偏函数创建类似于int2的功能int3 =  functools.partial(int, base=2)print(int3('1000000'))print(int2('1000000'))
6464

模块

  • 在Python中,一个.py文件就称之为一个模块(Module)
  • 避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)

使用模块

#!/usr/bin/env python3# -*- coding: utf-8 -*-' a test module '  ### 一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;__author__ = 'Michael Liao'import sysdef test():    args = sys.argv    if len(args)==1:        print('Hello, world!')    elif len(args)==2:        print('Hello, %s!' % args[1])    else:        print('Too many arguments!')if __name__=='__main__':    test()
['d:\\software\\python\\python37\\lib\\site-packages\\ipykernel_launcher.py', '-f', 'C:\\Users\\panxinbing\\AppData\\Roaming\\jupyter\\runtime\\kernel-80bc89a6-de0a-4d0b-bca1-d575da9e6e4f.json']Too many arguments!
  • sys模块有一个argv变量,用list存储了命令行的所有参数。argv至少有一个元素,因为第一个参数永远是该.py文件的名称
    运行python3 hello.py获得的sys.argv就是[‘hello.py’];
    运行python3 hello.py Michael获得的sys.argv就是[‘hello.py’, 'Michael]
  • Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败

作用域

  • 外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public
  • 类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途
  • 类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等

第三方模块

模块搜索路径

  • Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中

  • 添加自己的搜索目录

# 一是直接修改sys.path,添加要搜索的目录,这种方式在运行时修改,运行结束后失效import syssys.path.append('/Users/michael/my_py_scripts')print(sys.path)# 第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。# 注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响
['D:\\javaProject\\idea\\MatchZoo-master\\tutorials', 'd:\\software\\python\\python37\\python37.zip', 'd:\\software\\python\\python37\\DLLs', 'd:\\software\\python\\python37\\lib', 'd:\\software\\python\\python37', '', 'd:\\software\\python\\python37\\lib\\site-packages', 'd:\\software\\python\\python37\\lib\\site-packages\\matchzoo-2.2.0-py3.7.egg', 'd:\\software\\python\\python37\\lib\\site-packages\\win32', 'd:\\software\\python\\python37\\lib\\site-packages\\win32\\lib', 'd:\\software\\python\\python37\\lib\\site-packages\\Pythonwin', 'd:\\software\\python\\python37\\lib\\site-packages\\IPython\\extensions', 'C:\\Users\\panxinbing\\.ipython', '/Users/michael/my_py_scripts', '/Users/michael/my_py_scripts']

面向对象编程

类和实例

# 类中函数和普通函数的却别# 类中函数第一个单数永远是self,指向创建实例本身。普通函数则没有selfclass Student(object):    def __init__(self, name, score):        self.name = name        self.score = scorestudent = Student("333",333)

访问限制

# 如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__class student():    def __init__(self, name, score):        self.__name = name        self.score = score# 在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,#特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名# 有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,# 但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。#双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,#所以,仍然可以通过_Student__name来访问__name变量:

继承和多态

获取对象类型

### 使用type()type(123)std = student("name",333)type(std)
__main__.student
# 判断一个对象是否是函数import typesdef fn():    passtype(fn)==types.FunctionTypetype(abs)==types.BuiltinFunctionTypetype(lambda x: x)==types.LambdaTypetype((x for x in range(10)))==types.GeneratorType
True
# 判断一个变量是否是某些类型中的一种isinstance([1, 2, 3], (list, tuple))
True

使用dir()

获得一个对象的所有属性和方法

dir('ABC')
class MyObject(object):    def __init__(self):         self.x = 9    def power(self):        return self.x * self.xobj = MyObject()
# 通过getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态print(hasattr(obj, 'x'))print(getattr(obj, 'x'))# 可以传入一个default参数getattr(obj, 'z', 404)# 获得对象的方法getattr(obj, 'power')
True9

实例属性和类属性

实例属性属于各个实例所有,互不干扰;

类属性属于类所有,所有实例共享一个属性;

不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误。

面向对象的高级编程

使用__slot__

## 定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性, 只对当前实例起作用## 定义了一个class,直接给class绑定方法,所有的实例均可调用该方法## 使用__slot__可以限制实例的属性class Student(object):    __slots__ = ('name', 'age')s = Student() # 创建新的实例s.name = 'Michael' # 绑定属性'name's.age = 25 # 绑定属性'age's.score = 99 # 绑定属性'score'
---------------------------------------------------------------------------AttributeError                            Traceback (most recent call last)
in
7 s.name = 'Michael' # 绑定属性'name' 8 s.age = 25 # 绑定属性'age'----> 9 s.score = 99 # 绑定属性'score'AttributeError: 'Student' object has no attribute 'score'

使用@property

在绑定参数时,如果直接把属性暴露出去,虽然写起来很简单,但是,无法对参数进行校验

解决方案
1、使用get set方式,限制参数,但是在调用的时候比较繁琐,没有直接调用属性简单
2、Python内置的@property装饰器负责把一个方法变为属性调用

# 把一个getter方法变成属性,只需要加上@property就可以了# @score.setter,负责把一个setter方法变成属性赋值class Student(object):    __slots__ = ('__score')        @property    def score(self):        return self.__score        @score.setter    def score(self, value):        if not isinstance(value, int):            raise ValueError("score must be an integer")        if value < 0 or value > 100:            raise ValueError("score must between 0~100")        self.__score = valuestudent = Student()student.score = 60print(student.score)
60

多重继承

class Dog(MyObject,Student ):    pass
# 在设计类的继承关系时,通常,主线都是单一继承下来的,例如,Ostrich继承自Bird。# 但是,如果需要“混入”额外的功能,通过多重继承就可以实现,比如,让Ostrich除了继承自Bird外,再同时继承Runnable。# 这种设计通常称之为MixInclass Cat(MyObject,StudentMixIn):    pass

定制类

# __str__ 将类返回一个好看的字符串class Student(object):    def __init__(self, name):        self.__name = name    def __str__(self):        return 'Student Object (name: %s)' % self.__nameprint(Student("tom"))s = Student('Tom')# 直接显示变量的时候仍然不好看s
Student Object (name: tom)<__main__.Student at 0x247638b5ba8>

IO编程

文件读写

读文件

try:    f = open('D:\\javaProject\\idea\\MatchZoo-master\\tutorials\\test.txt', 'r')    content = f.read()    print(content)finally:    print('执行')    if f:        f.close()
test 执行
# 使用with读取文件,和try catch一样,但是比try catch 更简单with open('D:\\javaProject\\idea\\MatchZoo-master\\tutorials\\test.txt', 'r') as f:    content = f.read()    print(content)
test
# read(size)每次读取一个固定size字节的内容# readline() 每次读取一行# readlines()一次读取所有内容并按行返回listwith open('D:\\javaProject\\idea\\MatchZoo-master\\tutorials\\test.txt', 'r') as f:    first = f.read(1)    print(first)    line = f.readline()    print("line first" + line)    for lines in f.readlines():        print(lines)
Hline firstello, world!Hello, world!

file-like Object

像open()函数返回的这种有个read()方法的对象,在Python中统称为file-like Object。除了file外,还可以是内存的字节流,网络流,自定义流等等

读取二进制文件

f = open('/Users/michael/test.jpg', 'rb')f.read()
---------------------------------------------------------------------------FileNotFoundError                         Traceback (most recent call last)
in
----> 1 f = open('/Users/michael/test.jpg', 'rb') 2 f.read()FileNotFoundError: [Errno 2] No such file or directory: '/Users/michael/test.jpg'

读取字符编码

f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')f.read()
---------------------------------------------------------------------------FileNotFoundError                         Traceback (most recent call last)
in
----> 1 f = open('/Users/michael/gbk.txt', 'r', encoding='gbk') 2 f.read()FileNotFoundError: [Errno 2] No such file or directory: '/Users/michael/gbk.txt'

不规范编码处理

有些文件中可能存在一些不规范编码,如果直接使用open函数,会抛出异常,最直接简单的方法是使用ignore参数

f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')

写文件

调用open()函数时,传入标识符’w’或者’wb’表示写文本文件或写二进制文件

要写入特定编码的文本文件,请给open()函数传入encoding参数
以’w’模式写入文件时,如果文件已存在,会直接覆盖(相当于删掉后新写入一个文件)。如果我们希望追加到文件末尾怎么办?可以传入’a’以追加(append)模式写入

f = open('D:\\javaProject\\idea\\MatchZoo-master\\tutorials\\test.txt', 'w')f.write('Hello, world!')f.close()

你可以反复调用write()来写入文件,但是务必要调用f.close()来关闭文件。

当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。
只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。
忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用with语句来得保险

with open('D:\\javaProject\\idea\\MatchZoo-master\\tutorials\\test.txt', 'a') as f:    f.write('Hello, world!')

StringIO和BytesIO

StringIO

在内存中读写io

#getvalue()方法用于获得写入后的str。from io import StringIOf = StringIO()f.write("hello\n")s = f.getvalue()print(s)
hello
from io import StringIOf = StringIO('Hello!\nHi!\nGoodbye!')s = f.readline()print(s)f.write("666\n")print(f.getvalue())
Hello!Hello!666Goodbye!

BytesIO

使用BytesIO操作二进制数据

from io import BytesIOf = BytesIO()f.write('中文'.encode('utf-8'))print(f.getvalue())
b'\xe4\xb8\xad\xe6\x96\x87'
from io import BytesIOf = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')print(f.read())
b'\xe4\xb8\xad\xe6\x96\x87'

操作文件和目录

# 查看操作系统的类型 # posix说明系统是linux、unix或mac os X,如果是nt,就是windows系统import osprint(os.name)
nt
# 查看系统的详细信息import osos.uname()
---------------------------------------------------------------------------AttributeError                            Traceback (most recent call last)
in
1 # 查看系统的详细信息 2 import os----> 3 os.uname()AttributeError: module 'os' has no attribute 'uname'

转载地址:http://tfktn.baihongyu.com/

你可能感兴趣的文章
leetcode每日一题---15. 三数之和
查看>>
leetcode每日一题---面试题 16.18. 模式匹配
查看>>
地主的钱袋
查看>>
招新成绩统计
查看>>
webpack
查看>>
go部署
查看>>
配置swagger--go语言
查看>>
打印杨辉三角
查看>>
java中String类中常用方法
查看>>
flutter学习笔记:第一个APP应用
查看>>
哲学家进餐问题
查看>>
Python-Opencv学习总结(一):图像读取和获取图像特征
查看>>
实验十三:导出与导入
查看>>
第十五周.
查看>>
基于MVC模式的用户登录
查看>>
Java Swing搭建QQ登录界面
查看>>
Spring常用依赖及注解的使用
查看>>
解决Maven中资源过滤问题
查看>>
Springboot中解决Ajax请求跨域问题
查看>>
Keras软件安装
查看>>