飞污熊博客

静下心来做一件事

IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留, 由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。

通常,程序完成IO操作会有Input和Output两个数据流。当然也有只用一个的情况, 比如,从磁盘读取文件到内存,就只有Input操作,反过来,把数据写到磁盘文件里,就只是一个Output操作。

Stream(流)是一个很重要的概念,可以把流想象成一个水管,数据就是水管里的水,但是只能单向流动。 Input Stream就是数据从外面(磁盘、网络)流进内存,Output Stream就是数据从内存流到外面去。

阅读全文 »

现在是多核和并发时代,所以不管什么语言都要支持这个特性。并发是看上去同时执行,并行是在多核上同时执行。

我们先解释下线程和进程。简单来说,一个任务就是一个进程(Process)。 在一个进程内部,要同时干多件事,就需要同时运行多个进程内的”子任务”,这些子任务就叫线程(Thread)

线程是最小的执行单元,而进程由至少一个线程组成。如何调度进程和线程, 完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间。

多进程和多线程的程序涉及到同步、数据共享的问题,编写起来更复杂。

阅读全文 »

日期和时间是我们编程经常需要处理的事情,相比较其他语言,python中的日期和时间处理非常简洁。 datetime是python处理日期和时间的标准库。

python中有一个datetime模块,里面有个datetime类,这里大家先要弄清楚,很容易搞混。

所以我们获取当前日期和时间的代码如下:

1
2
3
4
5
6
from datetime import datetime

now = datetime.now() # 获取当前datetime
print(now)
print(type(now))
# <class 'datetime.datetime'>

如果仅导入·import datetime·,则必须引用全名datetime.datetimedatetime.now()返回当前日期和时间,其类型是datetime

阅读全文 »

字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。

正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则, 凡是符合规则的字符串,我们就认为它”匹配”了,否则,该字符串就是不合法的。

我们判断一个字符串是否是一个合法的电话号码分两步,首先创建一个符合电话号码规则的正则表达式, 然后用这个正则表达式来匹配这个字符串是否合法。

阅读全文 »

动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。我们在hello.py模块里定义一个Hello的 当Python解释器载入hello模块时,就会依次执行该模块的所有语句,执行结果就是动态创建出一个Hello的class对象。

我们说class的定义是运行时动态创建的,而创建class的方法就是使用type()函数。

type()函数既可以返回一个对象的类型,又可以创建出新的类型。

阅读全文 »

面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。 OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。 为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息, 并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。 自定义的对象数据类型就是面向对象中的类(Class)的概念。

阅读全文 »

python有着强大的表达式语法和函数特性,其中一个我的最爱便是装饰器。 在设计模式中,装饰器能够在不使用子类的情况下动态的修改函数、方法或类的功能。

当你需要扩展某个函数的功能却不想直接修改这个函数的时候,装饰器就可以派上用场了。 实现装饰器模式有很多种方法,但是python通过强大的语法支持来让这个变得相当容易。

在这篇文章中我将深入讲解Python的函数装饰器,并通过一系列的源码示例来彻底讲清楚这个东西。 所有例子都在Python2.7下运行通过,不过只需要稍作改变就可以运行在Python3上了, 甚至我猜测什么都不用改变都可以的,读者可以自己去试试。

本质上来讲,装饰器是以包装器形式工作的,其实就是在执行目标函数之前或之后加入自己的逻辑, 而不需要改变目标函数本身就可以增强它的功能,也就是说装饰了它。

阅读全文 »

在讲生成器之前,先讲讲python里面常用的几个常见的推导式:

列表推导式(list comprehension)

1
my_list = [f(x) for x in sequence if cond(x)]

字典推导式(dictionary comprehension)

1
my_dict = {k(x): v(x) for x in sequence if cond(x)}

集合推导式(set comprehension)

1
my_set = {f(x) for x in sequence if cond(x)}

生成器表达式(generator expression)

1
my_generator = (f(x) for x in sequence if cond(x))

对于大部分的python初学者而言,生成器和yield关键字比较难以理解。很多文章解释的不清楚, 这篇文章我想深入的讲解这个yield关键字,它到底是个什么东西,为什么它如此的重要,以及我们该如何去使用它。

注意:近些年来,随着越来越多的特性被加入到PEP中,生成器变得越来越强大。我在下一篇文章会深入讲解协程、多任务协作和异步I/O这些高阶知识,来见识下yield 的威力。

阅读全文 »

迭代(iteration)指的是去获取元素的一种方式,一个接一个。当你显式或隐式的使用循环来遍历某个元素集的时候,那就是迭代。

在Python里面,可迭代对象(iterable)和迭代器(iterator)有着特殊的含义。

  • iterable是实现了__iter__()方法的对象,该方法会返回一个iterator对象
  • iterator是实现了__iter__()__next__()方法的对象,__iter__()方法返回的是iterator对象本身

由此可见,iterableiterator的本质区别就是后者多了一个__next__()方法。 也就是说一个iterator对象必定是一个iterable对象。

阅读全文 »

模块和包都是用来组织代码用的,在python中一个模块就是一个.py文件,而一个包就是一个包含了__init__.py的文件夹。 使用模块最大的好处就是提高代码可维护性,我们在编写代码的时候通常会引用内置模块或第三方模块。

引入包是为了解决命名冲突问题,你可以把包当成是命名空间,比如你写的abc.py模块和其他人写的abc.py模块只要在不同的包中就不会冲突。 只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。

阅读全文 »