模块、面向对象

1. 内置函数(下)

  • filter(函数,序列)
def f(x):
    if x % 2 == 0:  #取偶数
        return True
print filter(f,range(10))
print filter(None,range(10))  #None是什么的都不做的函数

执行结果:

C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/t.py
[0, 2, 4, 6, 8]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
  • zip合并列表
l1 = [1,2,3]
l2 = ['a','b','c']
print zip(l1,l2)    #合并列表
print dict(zip(l1,l2))    #将列表转化为字典

执行结果

C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/t.py
[(1, 'a'), (2, 'b'), (3, 'c')]
{1: 'a', 2: 'b', 3: 'c'}
  • map(函数,序列)
def f(x):
   if x % 2 == 0:
        return True
print map(f,range(10))  #返回True或者False
print map(None,range(10))

执行结果:

C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/t.py
[True, None, True, None, True, None, True, None, True, None]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

对比filter,说明map针对的对象是序列里的元素,返回的是元素对应的处理结果。filter针对的是序列本身,返回符合函数条件的值。

def f(x,y):
    return x * y
print map(f,[1,2,3],[2,4,3])  #返回x*y的值

执行结果:

C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/t.py
[2, 8, 9]
  • reduce(函数,序列),从左到右针对每个元素处理
Help on built-in function reduce in module __builtin__:

reduce(...)
    reduce(function, sequence[, initial]) -> value
    
    Apply a function of two arguments cumulatively to the items of a sequence,
    from left to right, so as to reduce the sequence to a single value.
    For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
    ((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
    of the sequence in the calculation, and serves as a default when the
    sequence is empty.
  • filter/map和lambda合用
print filter(lambda x:x % 2 == 0,range(10))  #
[0, 2, 4, 6, 8]
print map(lambda x,y:x*y, range(5),range(5))
[0, 1, 4, 9, 16]
print reduce(lambda x,y:x+y, range(1,101))
     5050
  • 列表表达式--列表重写
In [2]: [i*2+10 for i in range(10)]  #i从1-10取值,返回i*2+10
Out[2]: [10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
In [3]: [i for i in range(10) if i%3 == 0]  #i从1-10取值,返回被3整除的数
Out[3]: [0, 3, 6, 9]

可以对比map和filter

2. 模块

  • 模块是Python组织代码的基本方式。
  • 一个Python脚本可以单独运行,也可以导入到另一个脚本中运行,当脚本被导入运行时,我们将其称为模块(module)。
  • 所有的.py文件都可以作为一个模块导入
  • 模块名与脚本的文件名相同
  • 例如我们编写了一个名为hello.py的脚本,则可以在另一个脚本中用import hello语句来导入它。

3. 包

  • Python的模块可以按目录组织为包
    创建一个包的步骤:
    • 创建一个名字为包名的目录
    • 在该目录下创建一个init.py文件,可以为空
    • 根据需要,在该目录下存放脚本文件或已编译的扩展及子包
    • import pack.m1, pack.m2, pack.m3
  • sys.path查看模块所在目录
In [6]: import sys

In [7]: sys.path  #输出的是列表
Out[7]: 
['',
 '/usr/bin',
 '/usr/lib64/python27.zip',
 '/usr/lib64/python2.7',
 '/usr/lib64/python2.7/plat-linux2',
 '/usr/lib64/python2.7/lib-tk',
 '/usr/lib64/python2.7/lib-old',
 '/usr/lib64/python2.7/lib-dynload',
 '/usr/lib64/python2.7/site-packages',
 '/usr/lib/python2.7/site-packages',
 '/usr/lib/python2.7/site-packages/IPython/extensions']

既然是列表,如果想插入自定义的路径,可以用.insert插入,或者append追加在最后

In [9]: sys.path.insert(1,'/root/py')  #因为列表第一个是空,第二个才是'/root/py'

In [10]: sys.path
Out[10]: 
['',
 '/root/py',    #已经插入
 '/usr/bin',
 '/usr/lib64/python27.zip',
 '/usr/lib64/python2.7',
 '/usr/lib64/python2.7/plat-linux2',
 '/usr/lib64/python2.7/lib-tk',
 '/usr/lib64/python2.7/lib-old',
 '/usr/lib64/python2.7/lib-dynload',
 '/usr/lib64/python2.7/site-packages',
 '/usr/lib/python2.7/site-packages',
 '/usr/lib/python2.7/site-packages/IPython/extensions']

删除自定义的目录:

In [23]: sys.path.remove('/root/py')

In [24]: sys.path
Out[24]: 
['',
 '/usr/bin',
 '/usr/lib64/python27.zip',
 '/usr/lib64/python2.7',
 '/usr/lib64/python2.7/plat-linux2',
 '/usr/lib64/python2.7/lib-tk',
 '/usr/lib64/python2.7/lib-old',
 '/usr/lib64/python2.7/lib-dynload',
 '/usr/lib64/python2.7/site-packages',
 '/usr/lib/python2.7/site-packages',
 '/usr/lib/python2.7/site-packages/IPython/extensions']
  • 总结:

模块是一个可以导入的Python脚本文件;
包是一些按目录组织的模块和子包,目录下有init.py文件,此文件可以存放包的信息;
导入模块和包的语法:
import , import as
from … import …

4. 练习创建模块并导入

  • 创建模块
#!/usr/bin/python
# -*- coding:utf8 -*-
# author: chawn
# date:

def wordCount(s):
    # 统计字符数,就是长度
    chars = len(s)
    # 统计单词数,先切成列表,在统计列表长度
    words = len(s.split())
    # 统计行数,就是统计换行符数量
    lines = s.count('\n')
    print lines,words,chars

s = open('/etc/passwd').read()
wordCount(s)

执行结果和wc一样:

[root@t1 py]# python 2.py 
31 56 1484
[root@t1 py]# wc /etc/passwd
  31   56 1484 /etc/passwd
  • 导入模块
    新建一个脚本3.py,里面就写一行import 1,不能写import 1.py,执行3.py
[root@t1 py]# vi 3.py
[root@t1 py]# python 3.py 
  File "3.py", line 2
    import 1.py
            ^
SyntaxError: invalid syntax

报错,这是因为模块命名不能用数字开头,改名再试

[root@t1 py]# vi 3.py
[root@t1 py]# python 3.py 
31 56 1484

[root@t1 py]# cat 3.py
#!/usr/bin/python
import wc

这时成功执行,此时看一下wc开头的文件,多了一个wc.pyc,这是被编译的文件,方便下次更快调用wc模块

[root@t1 py]# ls wc*
wc.py  wc.pyc
  • 通常我们调用模块是为了执行命令,比如这里,给3.py加一行wc.wordCount('asd'):
[root@t1 py]# python 3.py 
31 56 1484
0 1 3

虽然第二行是要的结果,但是第一行是模块自带的结果,并不需要。简单的办法是直接进模块把代码注释掉,还有一种方法可以互不干扰。
先介绍一下_name_,执行结果是_main_

[root@t1 py]# cat wc.py
#!/usr/bin/python
# -*- coding:utf8 -*-
# author: chawn
# date:

def wordCount(s):
    # 统计字符数,就是长度
    chars = len(s)
    # 统计单词数,先切成列表,在统计列表长度
    words = len(s.split())
    # 统计行数,就是统计换行符数量
    lines = s.count('\n')
    print lines,words,chars
print __name__
#s = open('/etc/passwd').read()
#wordCount(s)
[root@t1 py]# python wc.py
__main__

既然这样,可以加一个判断,如果模块在执行的时候name就是main,就输出模块自带的命令,否则不执行。看下面:

[root@t1 py]# cat wc.py
#!/usr/bin/python
# -*- coding:utf8 -*-
# author: chawn
# date:

def wordCount(s):
    # 统计字符数,就是长度
    chars = len(s)
    # 统计单词数,先切成列表,在统计列表长度
    words = len(s.split())
    # 统计行数,就是统计换行符数量
    lines = s.count('\n')
    print lines,words,chars
if  __name__ == '__main__':
    s = open('/etc/passwd').read()
    wordCount(s)

分别执行wc.py和3.py,结果互不干扰,正是需要的

[root@t1 py]# python wc.py
31 56 1484
[root@t1 py]# python 3.py
0 1 3

5. 导入包

  • 先创建int.py,包必备
  • 包名就是当前所在目录名
  • 回退进入上级目录(默认从当前目录找包,此时可以把包看成一个文件来理解)
  • 进入ipython测试
In [1]: from d08 import wc

In [2]: wc.wordCount('123\n')
1 1 4

如果想在任意目录下进入ipython测试,可以先sys.path导入包所在目录的路径:

In [1]: import sys
In [3]: sys.path.append('/root/py')  #导入包路径

In [4]: sys.path
Out[4]: 
['',
 '/usr/bin',
 '/usr/lib64/python27.zip',
 '/usr/lib64/python2.7',
 '/usr/lib64/python2.7/plat-linux2',
 '/usr/lib64/python2.7/lib-tk',
 '/usr/lib64/python2.7/lib-old',
 '/usr/lib64/python2.7/lib-dynload',
 '/usr/lib64/python2.7/site-packages',
 '/usr/lib/python2.7/site-packages',
 '/usr/lib/python2.7/site-packages/IPython/extensions',
 '/root/py']  #路径已经导入
In [5]: from d08 import wc  #导入包没有报错
  • 导入包的另外几种方式,可以对比导入后执行的命令:
    1.import d08.wc
In [6]: import d08.wc

In [7]: d08.wc('asd')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-cf4f56897f2b> in <module>()
----> 1 d08.wc('asd')

TypeError: 'module' object is not callable

In [8]: d08.wc.wordCount('asd')  #执行需要输入这么长的命令
0 1 3

2.对比from d08 import wc

In [9]: from d08.wc import wordCount

In [10]: wordCount('asd')
0 1 3

还有一种在导入时创建命令别名:

In [11]: from d08.wc import wordCount as wc

In [12]: wc('asd')  #此时的wc是定义的别名
0 1 3

6.面向对象介绍

类和对象
Python类定义
类属性
类方法

面向过程和面向对象编程
- 面向过程编程:函数式编程,C程序等
- 面向对象编程:C++,Java,Python等

类和对象:是面向对象中的两个重要概念
- 类:是对事物的抽象,比如:人类、球类
- 对象:是类的一个实例,比如:足球、篮球
实例说明:
- 球类可以对球的特征和行为进行抽象,然后可以实例化一个真实的球实体出来。

面向对象的主要思想是:
- 封装
- 继承
- 多态
这种思想方便解决较为复杂的项目,且维护起来较为容易。

类定义:
类把需要的变量和函数组合成一起,这种包含称为“封装”
class A(object):
类的结构:
class 类名:
成员变量 – 属性
成员函数 – 方法

  • 创建类:
class MyClass(object):
        def fun(self):
            print “I am function”
类的方法中至少有一个参数self

举例:

#!/usr/bin/python
# -*- coding:utf8 -*-
# author: chawn
# date:
class People(object):
    color = 'yellow'

ren = People()
print ren

C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
<__main__.People object at 0x03686DF0>

People()是类,ren是People()的一个对象,print ren直接打印对象,print ren.color打印对象的属性,这叫静态属性

class People(object):
    color = 'yellow'

ren = People()
print ren.color

C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
yellow

动态方法:定义一个和函数一样的方法

class People(object):
    color = 'yellow'  #属性
    def think(self):    #方法
        print "I am a thinker"

ren = People()
print ren.color
ren.think()    #调用方法

C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
yellow
I am a thinker

在方法里调用属性:

#!/usr/bin/python
# -*- coding:utf8 -*-
# author: chawn
# date:
class People(object):
    color = 'yellow'
    def think(self):
        self.color = 'black'    #调用属性
        print "I am a %s" % self.color
        print "I am a thinker"

ren = People()
print ren.color
ren.think()

C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
yellow
I am a black
I am a thinker