文章目录

  • 1. 数据类型和变量
  • 2. 编码和输出
    • 2.1 编码
    • 2.2 格式化输出
  • 3. 函数
    • 3.1 函数
    • 3.2 函数参数
  • 4. 数据结构及算法
    • 4.1 数据结构
    • 4.2 列表生成式
    • 4.3 生成器
    • 4.4 迭代器
  • 5. 函数式编程
    • 5.1 高阶函数
    • 5.2 匿名函数
    • 5.3 闭包
    • 5.4 装饰器Decorator
    • 5.5 偏函数
  • 6. 面向对象编程
    • 6.1 基础
      • 6.1.1 类Class
      • 6.1.2 访问限制
      • 6.1.3 获取对象信息
      • 6.1.4 属性
      • 6.1.5 多态
    • 6.2 @property
    • 6.3 多重继承
    • 6.4 定制类
    • 6.5 枚举类
  • 7. 调试
  • 8. 文件
    • 8.1 文件读写
    • 8.2 JSON文件读写
    • 8.3 StringIO与BytesIO
    • 8.4 操作文件和目录
  • 9. 更多

1. 数据类型和变量

  • 对于很大的数,python允许再数字中间以_分隔,比如1000000000和1_000_000_000是等价的
  • 如果字符串内部有很多字符都要转义,可以使用r""或r’'取消字符串内部的转义
  • 如果字符串内部有很多换行,可以使用多行字符串```,比如

  • python中可以对同一变量反复赋值,而且可以是不同类型的数据

2. 编码和输出

2.1 编码

  • ASCII编码1个字节,Unicode编码通常是2个字节(部分4字节),ASCII转Unicode直接前面补0

  • UTF-8编码是针对Unicode的一种可变长度字符编码,UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。

  • 在计算机内存中,统一使用Unicode编码,字符串是str类型,以字符为单位。当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码,是以字节为单位的bytes类型,bytes类型用b’'或b""表示

  • str类型通过encode()方法转换为指定编码(eg,ascii,utf-8)的bytes类型,bytes类型通过decode()方法转换为指定编码的str类型

  • 由于Python源代码也是一个文本文件,需要将该源码保存为UTF-8编码,比如源码开头有:

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    

    第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;

    第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。

2.2 格式化输出

  • %用来格式化字符串,比如

    print('I am %s, I am %d years old, I am %.2f cm in height.' % ('Zhang', 22, 180.5))# %s可以将任意类型转换为字符串输出
    print("I am %s, I am %s years old" % ('Zhang', 22))
    
  • 使用字符串的format()方法格式化输出

    print('I am {0}, I am {1:.2f}cm in height'.format('Zhang', 180.512))
    
  • 使用f-string(f开头的字符串),会进行相应的变量替换

    a, b = 1, 2.125
    print(f'a is {a}, b is {b:.2f}')
    

3. 函数

3.1 函数

  • 函数名其实就是一个指向函数对象的引用,可以把函数名赋给一个变量,相当于取了别名

    a = abs
    print(a(-1))
    
  • 函数的返回值其实是一个tuple,按位置取出

3.2 函数参数

  • 必选参数(也称位置参数)在前,默认参数在后

    • 如果在参数列表中加入斜杠/,则/前面的变量只能通过位置参数方式传参,而且不能有默认值
  • 默认参数必须是不可变对象(比如None,数字,字符串,bool)

    python可变类型和不可变类型的区别 python的可变和不可变数据类型

    • 默认参数的值在函数定义的时候已经确定

    • 默认参数如果没有赋值,那么默认参数重新指向默认值

      • 如果默认参数是不可变类型,函数中间改变参数的值时,相当于新建了一个对象,内存地址发生了改变
      • 但如果默认参数是可变类型,函数中间改变参数的值时,不会新建对象,内存地址不改变。因此下次使用该函数时默认参数的值会不再是初始值,eg:
      def func(lst = []): # 错误写法,应该携程lst = None,后面在函数内部进行if判断,然后初始化lst.append("end")print(lst)
      func()  # ['end']
      func()  # ['end', 'end']
      func()  # ['end', 'end', 'end']
      
    • 还要注意Python函数的参数传递是共享传参,即将实参的引用传递给函数对应的形参,因此对于不可变类型的数据经过传参在函数内部改变后,函数外的实参也会改变

  • 可变参数:用于接受多个(或0个)参数,且参数个数不确定,eg:

    def add(*numbers):   # 在函数内部,numbers是一个tuple,所以无法修改# add numbers
    # 用法1:
    add(1,2,3)# 用法2:
    lst = [1, 2, 3]
    add(*lst)
    
    • 同时可变参数可以收集未匹配的位置参数,元组解包的过程中会将每一个元素依次放入到位置参数
    • *出现在函数定义时,表示可变参数,*出现在函数调用时,表示解包功能
  • 关键字参数:接受多个(或0个)含参数名的参数,eg:

    def person(name, age, **kw): # 函数内部对kw(dict类型)的改动不会影响到函数外的实参,因为传入的是拷贝print('name', name, 'age', age, 'other', kw)
    extra = {'city': 'Beijing'}
    person('zhang', 22, **extra)
    
  • 命名关键字参数:用于限制关键字参数的名字,*后面的参数被视为命名关键字参数

    • 如果有可变参数,后面就不需要*

    • 命名关键字参数可以有默认值

       def person(name, *, age=22, city):passperson("zhang", city="beijing")
      
  • 参数组合:必选参数–>默认参数–>可变参数–>命名关键字参数–>关键字参数

4. 数据结构及算法

4.1 数据结构

  • tuple:当tuple中只有一个元素时,需要在该元素加一个逗号防止歧义(输出也有这个逗号),eg: tup = (1,)
  • 切片:可以对list,tuple, string切片操作

4.2 列表生成式

[表达式 for循环 过滤条件]

lst = [x if x % 5 == 0 else -x for x in range(1, 31) if x % 2 != 0 ]
# for x in range(1, 31)是for循环部分,if x % 2 != 0是过滤条件(不能有else语句)
# x if x % 5 == 0 else -x是表达式部分,必须有else语句(如果有if语句)

4.3 生成器

列表元素可以通过某种算法推算出来,节省内存

  • 使用方法1:类似列表生成式

    gen = (x*x for x in range(10))
    # 使用next(gen)获得generator的下一个返回值,generator对象是可迭代对象
    for x in gen:print(x)
    
  • 使用方法2:yield关键字

    def Fibonacci(max):n, a, b = 0, 0, 1while n < max:yield b  # pring(b)a, b, n = b, a+b, n+1
    for x in Fibonacci(6):print(x)
    

    generator函数在每次调用next()的时候执行,遇到yield关键字就返回,下次执行时从上次返回的yield关键字处继续执行,generator对象可迭代

  • 技巧:用生成器返回一个无限序列,比如返回奇数序列:

    def odd_iter():n = 1while True:n += 2yield n
    

4.4 迭代器

  • 可迭代对象Iterable:容器类(list,tuple,dict,set,str)和generator,凡是可迭代对象都可以迭代,enumerate函数将list转换成index-element pair

  • 迭代器Iterator:generator是Iterator(计算是惰性的),使用iter()Iterable转换为Iterator

    from collections.abs import Iterable, Iterator
    isinstance("abc", Iterable)
    

5. 函数式编程

5.1 高阶函数

​ 函数(名)作为参数传入另一个函数

  • map(f, Iterable) -> Iterator:将函数f作用在Iterable中每个元素(将运算规则抽象了,增加了可读性)

  • reduce(f, Iterable):reduce把结果继续和下一个元素进行累积运算,返回值是f的返回值类型需要先导入

    # 具体过程:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
    from functools import reduce
    
  • filter(f, Iterable) -> Iterator:将函数f作用在Iterable中每个元素,如果返回值是True就保留,否则丢弃

  • sorted(Iterable, key=func, reversed=False)

5.2 匿名函数

lambda 参数: 表达式,可以将匿名函数赋给一个变量

5.3 闭包

  • 外部函数返回内部函数时,外部函数的变量和参数仍然被返回的内部函数所引用

    def lazy_sum(*args):local_var = 0def sum():# calc result, use local_var and *argsreturn resultreturn sum
    
  • 返回的函数并非立刻执行,如果返回的函数中使用了相同的局部变量,最后函数执行是绑定到了相同的参数,这部分不是很懂

  • 如果内部函数修改外部函数的变量,直接修改是不行的(因为虽然内部函数可以使用外部函数的变量,但是没有初始化),需要使用nonloacl关键字表示该变量在外部函数中已经初始化了

    def lazy_sum(*args):local_var = 0def sum():nonlocal local_var   # 表示这个变量是外部函数的变量,且已经初始化为0tmp = 0    # 这是内部函数的局部变量,每次调用sum时重新初始化# calcreturn resultreturn sum
    

5.4 装饰器Decorator

在代码运行期间动态增加功能的方法,本质上是一个返回函数的高阶函数

  • 写法一:不带参数

    def log(func):@functools.wraps(func) # 在运行add函数创建函数对象时,eg:a=add,a的__name__属性不加这句变成了wrapper,对于某些依赖函数签名的代码会出错,加了之后a的__name__属性变成了adddef wrapper(*args, **kw):print(func.__name__)return func(*args, **kw)return wrapper@log
    def add(x, y):return x+yadd(1,2)
    # 如果不加@修饰器使用高阶函数的写法:log(add)(1,2)
    
  • 写法二:带参数

    def log(text):def decorator(func):@functools.wraps(func)def wrapper(*args, **kw):print(text, func.__name__)func(*args, **kw)print('end')return wrapperreturn decorator@log("test") # 注意装饰器的参数不能是形参,一定要赋值
    def add(x, y):return x+yadd(1,2)
    # 如果不加@修饰器使用高阶函数的写法:log("test")(add)(1,2)
    

5.5 偏函数

将函数的一个参数固定(即设置默认值),返回一个新的函数,使之调用更简单

par_func = functools.partial(func, *args, **kw)

6. 面向对象编程

6.1 基础

6.1.1 类Class

​ 相当于一种数据类型

6.1.2 访问限制

​ 双下划线变量是private变量,不要在类外直接修改

class Student(object):def __init__(self, name):self.__name = namedef get_name(self):print(self.__name)def set_name(self, name):self.__name = namestu = Student("zhang")
stu.get_name()
print()
stu.__name = "li"    # Python解释器将Student类中的__name变量修改成了_Student__name,此处的__name变量是一个新的变量了
stu.get_name()
print(stu.__name, stu._Student__name)
print()
stu.set_name("zhao")
stu.get_name()
print(stu.__name, stu._Student__name)

6.1.3 获取对象信息

  • isinstance()判断一个对象是否是某个类型,或者位于该类型的父类继承链上。并且可以判断一个变量是否是某些类型中的一类,eg:

    isinstance([1,2,3], (list, tuple))
    
  • dir()获取一个对象的所有方法和属性

  • hasattr(obj, 'x'):判断obj对象是否有属性x

  • getattr(obj, 'x', 404):获取obj对象的属性x,如果没有返回404

  • setattr(obj, 'x', 1):设置obj兑现的属性x

6.1.4 属性

​ 相同名称的实例属性将屏蔽类属性

  • 实例属性:

    class Student:def __init__(self):self.name = 'zhang'
    stu = Student()
    print(stu.name) # 使用实例名.实例属性来访问实例属性
    
  • 类属性:

    class Student:name = 'zhang'
    print(Student.name) # 使用类名.类属性来访问类属性
    

6.1.5 多态

​ 子类重写父类的方法

  • 比如函数func的参数是Animals类型,继承自Animals类型的Dog、Cat类型(对拓展开放)的实例同样可以传入func函数(对修改封闭)
  • 静态语言(eg:Java)如果函数参数是Animals类型,就必须传入Animals类型或是Animals类型的子类;但是动态语言(eg:Python)如果函数参数是Animals类型,只需要保证传入的对象中有函数中调用的方法即可(不需要必须是Animals类型,即鸭子类型)

6.2 @property

​ 将getter/setter方法简化为对属性的赋值和访问

  • 对实例属性使用getter和setter:

    class Student:def get_score(self):return self._scoredef set_score(self, score):''' type check '''self._score = scorestu = Student()
    stu.set_score(60)
    print(stu.get_score())
    
  • 使用@property

    class Student:@property    # 表明将score(原来的getter方法)当作类的属性def score(self):return self._score   # getter、setter操作的变量@score.setter  # @property创建了另一个装饰器@property.setter,可以将setter方法变成属性赋值,如果只设置@property而不设置@property.setter,则该属性被认为是只读属性def score(self, score):''' type check '''self._score = scorestu = Student()
    stu.score = 60 # 原来的setter方法
    print(stu.score)    # 原来的getter方法
    

6.3 多重继承

  • MixIn设计模式:以一个父类为主类,其他父类视为增加的功能

6.4 定制类

  • __str__:重新定义print类实例的输出

    class Student:def __str__(self):return 'Student object'
    print(Student())
    
  • __iter__:返回一个用于for循环的迭代对象,该迭代对象调用 __next__方法获取下一个值

    class Fibonacci(object):def __init__(self):self.a, self.b = 0, 1def __iter__(self): return self   # 实例本身就是迭代对象,故返回自己def __next__(self):self.a, self.b = self.b, self.a+self.breturn self.a
    for n in Fibonacci():if n > 100:breakprint(n)
    
  • __getitem__:按下标(或者key)取值,同样还有__setitem____delitem__

    class Fibonacci(object):def __getitem__(self, n): # 如果想实现切片操作,需要进一步完善a, b, = 1, 1for x in range(n):a, b = b, a+breturn a
    
  • __call__:对类的实例进行调用

    class Student(object):def __call__(self, txt):print("test: %s" % txt)
    s = Student()
    s("txt")  # 对实例进行调用
    callable(s) # 判断一个对象能否被调用
    
  • __slots__:Python可以给实例或类绑定方法或属性,使用__slots__可以限制绑定的实例的属性和方法

6.5 枚举类

将一组常量定义在一个类中,且该类不可变

from enum import Enum
Mon = Enum('Month', ("Jan", "Feb", "Mar")) # Month类型的枚举类
for name, member in Mon.__members__.items():print(name, '=>', member, ',', member.value)
print(Mon(1))       # 根据value的值获取枚举常量
print(Mon.Jan)      # 根据成员名称引用枚举常量
print(Mon['Jan'])
print(Mon.Jan.value)    # 获取计数,从1开始

7. 调试

  • 断言:可以使用python -O test.py关闭assert

    def func(x):assert x!=0, "x is zero"return x//10
    
  • 日志logging:将print替换为logging

8. 文件

8.1 文件读写

with open('tset.txt', 'r', encoding='utf-8') as f:# f.read() # 会将文件内容一次性读取for line in f.readlines():print(line.strip())   # 把末尾的'\n'删掉# 或者line=f.readline()循环读直到line==''
# 当文件写入磁盘时,操作系统不会将数据立刻写入磁盘,而是放到缓存中,f.close()才保证全部写入磁盘

8.2 JSON文件读写

  • json.dump(obj, f):python对象obj序列化到文件f
  • json.dumps(obj):将python对象obj序列化为json格式字符串
  • json.load(f):将文件f反序列化为python对象
  • json.loads():将json格式字符串反序列化为python对象

8.3 StringIO与BytesIO

  • StringIO:在内存中读写str,BytesIO:在内存中读写bytes,与读写文件有相同的接口

8.4 操作文件和目录

  • os.uname()获取详细的系统信息
  • os.environ查看系统变量
  • os.path.abspath('.')当前目录的绝对路径
  • os.path.join()将多个路径合成一个
  • os.path.split()将路径拆分为两个部分,后一部分为最后的目录或文件名
  • os.path.splitext()得到路径的文件拓展名
  • os.mkdir(), os.rmdir(), os.remove(), os.rename()
  • shutil.copyfile()文件复制

9. 更多

Python Cookbook 3rd Edition Documentation
Python中文指南
Python黑魔法手册

python基础:廖雪峰的官方网站Python(部分)笔记相关推荐

  1. 廖雪峰的官方网站Python教程练习题

    利用generator实现杨辉三角 # -*- coding:utf-8 -*- def triangles():L=[1]while(True):yield LL=[1]+[L[x]+L[x+1] ...

  2. python 廖雪峰_python学习(廖雪峰的官方网站)

    廖雪峰的官方网站. 请注意区分命令行模式和Python交互模式. 在命令行模式下,可以直接运行.py文件. 2运行其实和java运行一样 cd dir 3 print() input() 4数据类型 ...

  3. pythoniter雪峰_python学习(廖雪峰的官方网站)

    廖雪峰的官方网站. 请注意区分命令行模式和Python交互模式. 在命令行模式下,可以直接运行.py文件. 2运行其实和java运行一样 cd dir 3 print() input() 4数据类型 ...

  4. MySQL廖雪峰的官方网站

    一.目的: 1.记录一下在廖雪峰的官方网站自学MySQL 二.参考 1.廖雪峰的官方网站 https://www.liaoxuefeng.com/wiki/1177760294764384/11796 ...

  5. python 惰性序列_讨论 - 廖雪峰的官方网站

    @廖雪峰 首先你要理解埃氏筛法的原理,其实是很简单的. 然后用惰性序列实现埃氏筛法时,只能想象抽象过程,不能推导每一步计算机是怎么算的,就像神经网络模拟的人工智能算法,连设计者也无法理解计算机执行的步 ...

  6. python基础8(来自廖雪峰的官方网站)

    生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大 ...

  7. python基础7 (来自廖雪峰的官方网站)

    高级特性 迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). 在Python中,迭代是通过for ... in来 ...

  8. python基础6(来自廖雪峰的官方网站)

    高级特性 切片 取一个list或tuple的部分元素是非常常见的操作.比如,一个list如下: >>> L = ['Michael', 'Sarah', 'Tracy', 'Bob' ...

  9. python基础5(来自廖雪峰的官方网站)

    函数 定义函数 在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回. 我们以自定义一个求绝对值的 ...

最新文章

  1. 他入狱10年自学数学,如今凭借手稿发了篇论文,被同行评价“足以开辟数论新领域”...
  2. 玩转Mixly – 5、Arduino AVR编程 之 逻辑
  3. java的调试工具_2020年最佳Java调试工具(翻译)
  4. Time to First Byte(TTFB)与Web性能优化
  5. 关于处理小数点位数的几个oracle函数
  6. 【Cinemachine智能相机教程】VirtualCamera(四):Noise属性
  7. Oracle instantclient 11.2 (64位)安装与配置tnsnames.ora,并使用PL/SQL Develpoer14(64位)连接数据库
  8. 概率论 方差公式_【考研数学】概率论与数理统计
  9. 如何自学python-零基础如何自学成为Python高手?
  10. 未能创建可接受的游标。
  11. js自动生成html报表,JavaScript实现动态生成表格
  12. travis ci java_[转]Travis Ci的最接底气的中文使用教程
  13. 分支-07. 比较大小(10)
  14. 统计学习三要素个人理解
  15. 项目开发过程中的管理规范
  16. 【逍遥模拟器】注册微信提示环境异常怎么解决?
  17. 常用的arm汇编指令(3) -学无止尽,积土成山,积水成渊
  18. android 绘画笔迹回放_一种基于可缩放矢量图形的安卓平台笔迹回放方法及装置与流程...
  19. 毒液蛋白质相互作用分析
  20. 002. 顺应自然,人才会活的好

热门文章

  1. 制作android动态壁纸,使用视差滚动制作Android动态壁纸
  2. Leetcode_49_Anagrams
  3. 金融量化-金叉和死叉
  4. (MATLAB代码分享,可运行)基于改进遗传算法的柔性作业车间调度优化研究
  5. echarts多线图表 提示框自定义
  6. CSS——高度塌陷以及解决方法
  7. oracle数据库在mybatis中的数值类型(NUMBER型)
  8. 《社会动物——爱、性格和成就的潜在根源》读后感及摘录(1)
  9. 猫和老鼠服务器未响应是怎么回事,猫和老鼠手游怎么玩不了 游戏设置及异常解决方法...
  10. 2020-12-19