适合于新手的Python学习笔记

Python基础注意点

字符串是以单引号'或双引号"括起来的任意文本,比如'abc',"xyz"等等。

如果'本身也是一个字符,那就可以用""括起来,比如"I'm OK"包含的字符是I,',m,空格,O,K这6个字符

如果字符串内部既包含'又包含"怎么办?可以用转义字符\来标识,比如:

1
'I\'m \"OK\"!'
表示的字符串内容是:

1
I'm "OK"!
空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值

list与tuple

list是一种有序的集合,可以随时添加和删除其中的元素,表示如classmates = ['Michael', 'Bob', 'Tracy']
tuple和list非常类似,但是tuple一旦初始化就不能修改,表示如classmates = ('Michael', 'Bob', 'Tracy')
不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。

只有1个元素的tuple定义时必须加一个逗号,,不然定义的不是tuple,是元素本身
Python函数注意点

必选参数在前,默认参数在后,否则Python的解释器会报错

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple,方式为*args

而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict,方式为**kw

使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个*作为特殊分隔符。如果缺少*,Python解释器将无法识别位置参数和命名关键字参数

参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数

对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的

高级特性

生成器

generator:一边循环一边计算的机制

创建生成器

把一个列表生成式的[]改成()

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator

generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)
调用该generator时,首先要生成一个generator对象,然后用next()函数不断获得下一个返回值:

>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
迭代器

凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象
高阶函数

把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式

def add(x, y, f):
    return f(x) + f(y)

>>> add(-5, 6, abs)
11
map/reduce

map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回

把list所有数字转为字符串:

1
2
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

如把str转换为int:

>>> from functools import reduce
>>> def fn(x, y):
...     return x * 10 + y
...
>>> def char2num(s):
...     return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
...
>>> reduce(fn, map(char2num, '13579'))
13579
filter

`filter()`把传入的函数依次作用于每个元素,然后根据返回值是`True`还是`False`决定保留还是丢弃该元素

例如,在一个list中,删掉偶数,只保留奇数,可以这么写:

def is_odd(n):
    return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 结果: [1, 5, 9, 15]
注意到filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list

sorted

按绝对值大小排序:

>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
返回函数

一个函数可以返回一个计算结果,也可以返回一个函数

返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量。

闭包:

def foo():
    m=3
    n=5
    def bar():
        a=4
        return m+n+a
    return bar
>>>bar =  foo()
>>>bar()
12

bar在foo函数的代码块中定义。我们称bar是foo的内部函数。

在bar的局部作用域中可以直接访问foo局部作用域中定义的m、n变量。
简单的说,这种内部函数可以使用外部函数变量的行为,就叫闭包

偏函数

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

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85
模块

在Python中,一个.py文件就称之为一个模块(Module)

每一个包目录下面都会有一个__init__.py的文件,__init__.py本身就是一个模块,模块名为包名

类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等

之所以我们说,private函数和变量“不应该”被直接引用,而不是“不能”被直接引用,是因为Python并没有一种方法可以完全限制访问private函数或变量,但是,从编程习惯上不应该引用private函数或变量

面向对象

在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问

限制实例的属性:定义一个特殊的__slots__变量,来限制该class实例能添加的属性

class Student(object):
    __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称

然后,我们试试:

>>> s = Student() # 创建新的实例
>>> s.name = 'Michael' # 绑定属性'name'
>>> s.age = 25 # 绑定属性'age'
>>> s.score = 99 # 绑定属性'score'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'
把一个getter方法变成属性,可以加上@property,把一个setter方法变成属性赋值可以加上@score.setter

如:

class Student(object):
    @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 = value

外部调用

>>> s = Student()
>>> s.score = 60 # OK,实际转化为s.set_score(60)
>>> s.score # OK,实际转化为s.get_score()

Python允许使用多重继承,这种设计通常称之为MixIn

动态创建类type()

>>> def fn(self, name='world'): # 先定义函数
...     print('Hello, %s.' % name)
...
>>> Hello = type('Hello', (object,), dict(hello=fn)) # 创建Hello class
>>> h = Hello()
>>> h.hello()
Hello, world.
>>> print(type(Hello))
<class 'type'>
>>> print(type(h))
<class '__main__.Hello'>

要创建一个class对象,type()函数依次传入3个参数:

class的名称;
继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。
IO编程

文件读写

在Python中,文件读写是通过open()函数打开的文件对象完成的。在Python中这种对象统称为file-like Object。除了file外,还可以是内存的字节流,网络流,自定义流等等

使用with语句操作文件IO是个好习惯,它自动帮我们调用close()方法,如:

with open('/path/to/file', 'r') as f:
    print(f.read())

多进程

Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。

子进程永远返回0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。

时间: 2024-09-15 02:57:07

适合于新手的Python学习笔记的相关文章

Python学习笔记(一)(基础入门之环境搭建)_python

  Python入门       本系列为Python学习相关笔记整理所得,IT人,多学无害,多多探索,激发学习兴趣,开拓思维,不求高大上,只求懂点皮毛,作为知识储备,不至于落后太远.      本文主要介绍Python的相关背景,环境搭建. 一.了解Python      1,关于Python的语言特点:      借用Python官网Https://www.python.org的解释: Python is powerful... and fast; plays well with other

python学习笔记第二章:安装python

记得上次写python的学习笔记是三个月以前了,期间看过,也放下过,这次要坚持下来,一鼓作气,吃下python. 本文内容主要是根据<Python 简明教程>和自己的一些理解去写的,有问题,还请指出. 一.Linux 下安装 如果你使用的是linux操作系统,那么恭喜你,你基本上可以不用去安装python,因为大多数linux的操作系统在安装系统的时候就已经默认安装了python. 要测试你的系统是否已经安装了python,可以执行如下命令 python -v 显示如下的python版本信息,

python学习笔记第三章:最初的步骤

今天从笔记的标题来看,你可能会很困惑,什么"最初的步骤"?这个标题是我引用了<python简明教程>中第三章的标题,给大家解释下就会都明白了. "最初的步骤"主要讲的就是 你刚才学习.练习python所用到的一些编辑器和执行python代码的方式. 一.使用带提示符的编辑器 "带提示符的编辑器" 也就是linux系统使用的终端,Windows系统中使用的命令提示符. 在linux终端shell提示符下输入python,启动pthon解

Python学习笔记之浅拷贝和深拷贝

在Python中对象的复制有三种一般的复制,浅拷贝,深拷贝,那么他们有什么区别呢 一般的复制 #encoding:utf-8 #定义一个嵌套集合 lista=[1,2,3,[4,5,6,[7,8,9]]] listb=lista #分别打印出 lista和listb的地址值 print id(lista) #4511103096 print id(listb) #4511103096 #修改lista中的内容,listb中的内容也会跟着修改 lista[0]=0 print lista #[0,

Python学习笔记(二)基础语法_python

学习Python,基本语法不是特别难,有了C的基本知识,理解比较容易.本文的主要内容是Python基础语法,学完后,能熟练使用就好.(开发环境依然是Python2.7,简单使用)一,基本知识1,不需要预先定义数据类型(此说法值得商榷,姑且这么说吧),这是与其他语言的最大不同(如C,C++,C#,Delphi等) 复制代码 代码如下:  >>> x=12 >>> y=13 >>> z=x+y >>> print z 25 注意:尽管变量

python 学习笔记第四章:基本概念

本章主要讲了python中的一些基本概念,这些是经常用到的,也是你必须要理解的. 一.字面意义上的常量 所谓字面意义上的常量就是类似1.2.3.Hello.你好,这样的数或者字符串,你能从字面上理解它的意思,就是字面意义上的常量. 二.数 在python中有四种类型的数:整数.长整数.浮点数.复数. * 2是一个整数的例子 * 10000是一个长整数的例子(长整数就是大一点的整数) * 3.14是一个浮点数的例子 * (-5+4j)是一个复数的例子 三.字符串 字符串是字符的序列,也可以理解为就

python学习笔记:语言、调试、语法、变量、表达式

python是编程语言的一种,有着传统编程语言的强大性和通用性,同时也借鉴了简单脚本和解释语言的易用性.总结一句话来概括就是:很好很强大! 1.编程语言就是编写程序的语言,而程序是根据语言提供的指令,按照一定的逻辑顺序,对获得的数据进行运算,并将结果最终返回给我们的指令和数据的组合.语言分为两种: 低级语言:用英文单词或单词的缩写代表计算机执行的指令,使编程的效率和程序的可读性都有了较大的提高.    高级语言:是人类逻辑思维的程序化.数字化和精确化数学描述,翻译成机器代码有两种方法,解释和编译

[Python]学习笔记之文件和异常

python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目录名:os.listdir() 函数用来删除一个文件:os.remove() 删除多个目录:os.removedirs(r"c:\python") 检验给出的路径是否是一个文件:os.path.isfile() 检验给出的路径是否是一个目录:os.path.isdir() 判断是否是绝对路

Python学习笔记之常用函数及说明_python

基本定制型 复制代码 代码如下: C.__init__(self[, arg1, ...]) 构造器(带一些可选的参数)C.__new__(self[, arg1, ...]) 构造器(带一些可选的参数):通常用在设置不变数据类型的子类.C.__del__(self) 解构器C.__str__(self) 可打印的字符输出:内建str()及print 语句C.__repr__(self) 运行时的字符串输出:内建repr() 和'' 操作符C.__unicode__(self)b Unicode