从零开始的PY交易: Python语言介绍

@oaoouo 2017年10月2日

目录

Python语言基础

Python简介

Python诞生于1991年, 是作者guido van rossum为了打发圣诞节无聊假期hacking的一个项目. 名字来源于喜剧monty python's flying circus.
guido
Python语法主要借鉴了abc、c、perl; Python的设计目标是简单易读 以及可扩展.
更多关于Python的历史点这里

Python语言结构

Python是一门解释型语言(动态语言).

----------------------
|       源代码        |
----------------------
          | 每行代码
          v
----------------------
|       解释器        | -> 还可以在交互模式下运行
----------------------
          |
          v
----------------------
|       字节码        | -> 可重用的字节码保存在.pyc文件中
----------------------
\/\/\/\/\/\/\/\/\/\/\/
    跨平台运行

Python解释器负责将Python源程序翻译成字节码, 官方实现是CPython. 在终端键入python, 可以进入Python解释器交互模式. 推荐ptpython、ipython]等具有自动补全以及语法高亮的Python交互解释器.

Python数据类型

Python中一切皆为对象, 所有变量、类、数据类型都是Object类的对象.
Python变量的声明和初始化不需要声明类型(这是Python方便的一点也是之所以慢的原因). 比如创建一个名称为a值为1.4的变量:

>> a = 1.4

Python解释器在解释这一行时会自动根据右边的值判断左边变量的类型(这里是float)并分配空间.
注意啦, 这里的a只是一个引用指向在堆上分配的存储1.4的内存, 每当这块内存被新的标签引用时, 引用计数就会加一, 方便gc在空闲的时候进行垃圾回收.

Python的对象分为可变(mutable)不可变对象(immutable)两大类, 元组、数值、字符串属于不可变对象; 字典和列表属于可变对象. 举个例子:

>>> a = 1
>>> b = a
>>> a = 2
>>> id(a) == id(b) # id(obj)获取obj内存地址的10进制表示
False

因为数值型对象是不可变的, 所以a=2会新开辟一块内存存储2, 将a变量绑定到新的内存.

>>> a = [1]
>>> b = a                                  
>>> a[0] = 2                               
>>> id(a) == id(b)                         
True

因为列表是可变对象, 所以修改a引用的列表不会创建新的列表对象.

接下来具体说说数值、字符串、列表、元组和字典.

数值

整数、浮点数(单精度、双精度)都属于数值类型, Python中创建该类型的变量很简单:

>>> a = 1.4
>>> print(a)
1.4

字符串

相比于C中的字符数组、Java中的String类. Python字符串的创建和使用简直太方便了.

>>> s = "oaoouo" # 双引号和单引号都可以
>>> print(s)
"oaoouo"

Python内置了大量字符串操作函数, 比如:

>>> s = "1;2;3;4;5"
>>> s.split(';')  # 根据;分割字符串s
['1', '2', '3', '4', '5']

字符串拼接也很简单:

>>> s1 = "neo1218"
>>> s2 = "oaoouo"
>>> s1 + s2
"neo1218oaoouo"

字符串处理体现了Python语言简洁、优雅的设计理念, 使得Python非常适合Web开发等需要大量处理字符串的开发场景.
Python是一门动态语言, 在程序运行时分配内存, 所以静态语言中的内存优化策略在Python中无法实现(比如C#中相同内容的字符串变量只引用一块内存). Python怎么办呢? 那只有靠猜了, Python会缓存常用的字符串和小整数(-5~120), 比如:

>>> a = 1
>>> b = 1
>>> a is b
True

这里的1就被缓存起来了.
字符串的缓存有点小复杂:

>>> a = "短字符串"
>>> b = "短字符串"
>>> a is b
True
>>> a = "长字符串"*1000
>>> b = "长字符串"*1000
>>> a is b
False
>>> a = "短 字符串"
>>> b = "短 字符串"
>>> a is b
False

python会缓存短字符串, 但是如果短字符串中有空格则不会被缓存orz.个人理解, 使用比较频繁的字符串就是变量名了(字母、数字、下划线), 所以进行缓存. 毕竟缓存也是需要内存开销的, 所以缓存大整数、长字符串就得不偿失了.

列表

Python列表功能类似C中的数组, 使用起来非常简单.

创建列表:

>>> l = [1, 2, 3, 4, 5]

索引列表中的元素:

>>> l[0] = 1
>>> l[2] = 3
>>> l[-1] = 5  # 特色, 还可以反向索引:)

切片:

>>> l[0:4]
[1, 2, 3, 4]
>>> l[-1: 2: -1]  # 第三个-1表示反向索引
[5, 4]
>>> l[0:4:2]  # 第三个2表示每隔2个元素
[1, 3]

列表属性:

>>> len(l)  # 列表的长度
5
>>> sum(l)  # 列表中元素的和
15

for...in遍历列表:

>>> for i in l:
>>> .... print(l),
>>> 1 2 3 4 5

字典

字典是hash表数据结构, 存储键值极其对应关系.

创建字典:

>>> d = {'name': 'oaoouo'}  # 第一个元素是键(不可变改变类型)
>>>                          # 第二个元素是值(任意类型)

根据字典的键取值:

>>> d['name']  # or d.get('name')
>>> 'oaoouo'

向字典中添加键值:

>>> d['age'] = 22  # 'age'键不在字典中, 所以添加; 如在字典中则修改键值.
>>> d
{'name': 'oaoouo', 'age': 22}

返回字典中的所有键or键值

>>> d.keys()
['age', 'name']
>>> d.values()
[22, 'oaoouo']

最后说一下, 字典是无序的, 它主要用来存储, 与键的顺序无关.

元组

元组简单理解就是不可变的列表.

创建元组:

>>> t = (1, 2, 3, 4, 5)

元组也可以向列表一样索引、切片、遍历.

Python基本语句

条件语句

Python条件语句的关键字有ifelseelse if 或者简写elif. 举个小栗子:

if (a == 1):
    print('one')
elif (a == 2):
    print('two')
else:
    print(None)

上面这段代码还可以省略最后一个else:

if (a == 1):
    print('one')
elif (a == 2):
    print('two')
print(None)

循环语句

Python循环有for...in循环while循环. 先举个while循环的例子:

while (a = 1):
    print("oaoouo ahahaha")

如果是永久循环, while (True) 就行啦!

for...in循环可以用于遍历可迭代对象, 由于这一篇是入门, 所以就不具体介绍可迭代对象了, 像之前的列表和元组都是可迭代对象.
那么如何像C中for循环一样拿到迭代元素在列表中的位置呢? 这就需要用到enumerate函数啦:

>>> for index, value in enumerate([1, 2, 3, 4, 5]):
>>> .... print({index: value})
{0: 1} {1: 2} {2: 3} {3: 4} {4: 5}

列表生成式和元组生成式

比如我想构造这样的一个列表: [(key1, value1), (key2, value2)], 列表的元素是一个元组, 元组里分别是字典的键和键值, 我们可以这样写:

>>> d = {'name': 'oaoouo', 'age': 22}
>>> l = []             
>>> .... for i, j in enumerate(d.keys()):           
>>> ....     l.append((j, d.values()[i]))
>>> l
[('age', 22), ('name', 'oaoouo')]

但用列表生成式一行代码就搞定了!

>>> l = [(j, d.values()[i]) for i, j in enumerate(d.keys())]
>>> l
[('age', 22), ('name', 'oaoouo')]

当然用Python内置的zip函数就更简单了...orz

>>> l = zip(d.keys(), d.values())
>>> l
[('age', 22), ('name', 'oaoouo')]

列表生成式生成的是列表, 元组生成式生成的是生成器, 把列表生成式[]改成元组()就行了:

>>> l = ((j, d.values()[i]) for i, j in enumerate(d.keys()))
>>> l
<generator object <genexpr> at 0x7f1a4e0b62d0>

至于什么是生成式, 这篇就不说了.

Python函数

Python函数使用def关键字创建:

>>> def test_func(x):
>>> ....    if x > 1:
>>> ....       return 1
>>> ....    return 0
>>> print(test_func(1))
0

Python面向对象

Python类使用class关键字创建:

class Man(object):  # object是所有类的基类, Python3中可以不写.
    def __init__(self, name, age):
        # __init__是初始化方法. 构造函数是__new__
        self.name = name
        self.age = age

    def get_info(self):
        print(self.name, self.age)

    @classmethod
    def this_is_a_classmethod():
        pass

    @staticmethod
    def this_is_a_staticmethod():
        pass

    def __repr__(self):
        # 类对象的默认表示
        return "<Man(name=%s, age=%s)>" % (name, age)

使用:

>>> oaoouo = Man("oaoouo", 22)
>>> oaoouo
<Man(name=oaoouo, age=22)>
>>> oaoouo.get_info()
("oaoouo", 22)

Python面向对象没有Java、C#这样严格, 没有各种控制访问的关键字(public、private、protected、final...), 主要还是靠自觉...

Python输入输出

从标准输入到标准输出
Python从标准输入中读取字符串使用raw_input()函数, 结合while循环就可以读取多行以回车换行分割的字符串:

>>> cnt = 3
>>> l = []
>>> while cnt:
...     l.append(raw_input())
...     cnt -= 1
1 2 3
1 2
3
>>> print(l)
['1 2 3', '1 2', '3']

至于输出, print就行啦!

Python读写文件
使用内置的open函数打开文件拿到文件操作句柄f, 使用f.read()f.write()即可进行文件读写.

>>> f = open('./test.txt')
>>> content = f.read()
'this is a test file\nyes, test\nhahahhahahahahha\n'
>>> content.split('\n')
['this is a test file', 'yes, test', 'hahahhahahahahha', '']  # 每个元素就是一行, 是不是很有用!
>>> f.close()

最后不要忘记调用f.close()将打开的文件从内存写回硬盘哦. 如果实在记不住调用f.close(), 不用烦, with语句来帮你:

>>> with open('./test.txt') as f:
>>>     content = f.read()
>>>     print(content.split('\n'))
['this is a test file', 'yes, test', 'hahahhahahahahha', '']

with语句会自动帮你清理上下文, 调用f.close()!
接下来, 继续举一个写文件的例子:

>>> with open('./test.txt', 'rw+') as f:  # 'rw+'表示可读、可追加写
>>>     f.write('new content')
>>> f = open('./test.txt')
>>> f.read()
'this is a test file\nyes, test\nhahahhahahahahha\nnew content\n'
>>> f.close()

常用的Python内置模块

Python除了提供了各种好用的函数外, 还提供了很多有用的模块, 比如ossysshutil等.
比如platform模块可以获取操作系统平台信息:

>>> import platform
>>> platform.linux_distribution()
('Kali', 'kali-rolling', 'kali-rolling')

Python应用举例

web方向

数据处理方向

awesome_python

资源附录