Python for Astronomy

Python 基础知识

何勃亮
中国科学院国家天文台 中国虚拟天文台 (China-VO)

Outline

  • Python 基础
  • Python 科学计算
  • Python 与天文学计算
  • 案例分享
    • 赵永恒: 使用Python进行历法计算
    • 余恒: 用Python搞定星表
    • 王鑫:使用Python方便快捷高效的载入输出数据,浅谈yaml在天文中的应用

课程特点

  • 不特别讲述深奥的知识点,比如面向对象编程,模块和包的开发等
  • 实用性,着重分解最常用的一些功能和用法
  • 案例分享

Python 基础知识

  • Python 简介
  • Python 语法
  • Python 容器
  • Python 代码风格(PEP8)
  • 软件包管理
  • Python 2 和 Python 3
  • Python 编程范式

Python 简介

历史

Python的创始人为吉多·范罗苏姆(Guido van Rossum)。1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承。之所以选中Python作为程序的名字,是因为他是BBC电视剧——蒙提·派森的飞行马戏团(Monty Python's Flying Circus)的爱好者。ABC是由吉多参加设计的一种教学语言。就吉多本人看来,ABC这种语言非常优美和强大,是专门为非专业程序员设计的。但是ABC语言并没有成功,究其原因,吉多认为是非开放造成的。吉多决心在Python中避免这一错误,并获取了非常好的效果,完美结合了C和其他一些语言。

就这样,Python在吉多手中诞生了。实际上,第一个实现是在Mac机上。可以说,Python是从ABC发展起来,主要受到了Modula-3(另一种相当优美且强大的语言,为小型团体所设计的)的影响。并且结合了Unix shell和C的习惯。

目前吉多仍然是Python的主要开发者,决定整个Python语言的发展方向。Python社区经常称呼他是仁慈的独裁者。

Python 2.0于2000年10月16日发布,增加了实现完整的垃圾回收,并且支持Unicode。同时,整个开发过程更加透明,社区对开发进度的影响逐渐扩大。Python 3.0于2008年12月3日发布,此版不完全兼容之前的Python源代码。不过,很多新特性后来也被移植到旧的Python 2.6/2.7版本。

Python是完全面向对象的语言。函数、模块、数字、字符串都是对象。并且完全支持继承、重载、派生、多重继承,有益于增强源代码的复用性。Python支持重载运算符,因此Python也支持泛型设计。相对于Lisp这种传统的函数式编程语言,Python对函数式设计只提供了有限的支持。有两个标准库(functools, itertools)提供了与Haskell和Standard ML中类似的函数式程序设计工具。

虽然Python可能被粗略地分类为“脚本语言”(script language),但实际上一些大规模软件开发项目例如Zope、Mnet及BitTorrent,Google也广泛地使用它。Python的支持者较喜欢称它为一种高级动态编程语言,原因是“脚本语言”泛指仅作简单程序设计任务的语言,如shell script、VBScript等只能处理简单任务的编程语言,并不能与Python相提并论。

Python本身被设计为可扩充的。并非所有的特性和功能都集成到语言核心。Python提供了丰富的API和工具,以便程序员能够轻松地使用C、C++、Cython来编写扩充模块。Python编译器本身也可以被集成到其它需要脚本语言的程序内。因此,有很多人把Python作为一种“胶水语言”(glue language)使用。使用Python将其他语言编写的程序进行集成和封装。在Google内部的很多项目,例如Google App Engine使用C++编写性能要求极高的部分,然后用Python或Java/Go调用相应的模块。《Python技术手册》的作者马特利(Alex Martelli)说:“这很难讲,不过,2004年,Python已在Google内部使用,Google召募许多Python高手,但在这之前就已决定使用Python。他们的目的是尽量使用Python,在不得已时改用C++;在操控硬件的场合使用C++,在快速开发时候使用Python。”

Python 老爹怎么说(PyCon2016)

Guido van Rossum

  • Python的性能提升 Python 3的性能已经跟上来了,比2012年时要快的多。另外,还有像PyPy这样的Python实现。有一些新版本的Python解释器也在试图提升速度。 其实,Python的性能并没有人们说的那样差,而且因为Python大部分是用C语言实现的,很多事情做起来可以和C语言一样快。我还是认为,Python对于大部分事情来说已经足够快了。

    尽管没有往Python 3中新增特性以改善速度,但是我们已经让语言的很多方面变快了:比如,引用计数比以前快了些。主要还是优化现有的代码,但是作为用户来说,很难注意到区别。

    而且如果你急需提升某个Python程序的速度,可以尝试使用PyPy。它已经足够成熟,值得尝试。

  • SciPy和NumPy 这两个团队正在推动使用Python替代Matlab。我们的替代方案是开源的,而且更好,他们能做到的。他们正在将Python带领到从未想象过的领域。他们开发出了像Jupyter Notebooks这样的工作,可以在浏览器中使用交互式Python。

Who use Python?

  • Radio / Submm (NRAO, ESO, JAOJ, CSIRO): CASA
  • IR: HIPE (Herschel Interactive Processing Environment)
  • Optical: STSci (PyRAF, PyFITS)
  • Optical: Gemini IRAF package - new development in Python
  • Optical: ESO PyMidas
  • X-ray: Chandra CIAO and Sherpa
  • Gamma-ray: Fermi Science Analysis tools

安装

yum -y install gcc gcc-c++ make gcc-gfortran bzip2 bzip2-devel bison \
flex readline-devel sqlite-devel gdbm-devel xz-devel xz-libs

./configure --prefix=/usr/local --enable-ipv6 --enable-shared
make -j4
sudo make install

Anaconda

  • NumPy
  • SciPy
  • IPython / Jupyter
  • Matplotlib
  • AstroPy
  • Spyder

更多软件列表:https://docs.continuum.io/anaconda/pkg-docs

Python 语法

数据类型

  • 整形 Integer
  • 浮点型 Floating
  • 复数 Complex
  • 字符串 String
In [1]:
a = 10
b = 12.232
c = 10. + 3j
d = 'hello Python'
a, b, c , d
Out[1]:
(10, 12.232, (10+3j), 'hello Python')

算数运算符

  • +
  • -
  • *
  • /
  • 取模 %
  • **
In [2]:
a = 12 + 21
b = 12 - 21
c = 12 * 21
d = 12 / 21
e = 12 % 21
f = 12 ** 21
a, b, c, d, e, f
Out[2]:
(33, -9, 252, 0.5714285714285714, 12, 46005119909369701466112)

控制语句

  • 控制语句:if, else, elif
  • 判断
    • >
    • <
    • ==
    • >=
    • <=
    • !=
  • 多个判断语句可以使用: and, or, not

下面的情况会被任务是False

  • False
  • None
  • 0
  • 0.0
  • '' 空字符串
  • []
  • {}
  • ()
  • set()

循环

常见两种模式:

for ... in ... : 
    statement
while ... : 
    statement

break

break 用来跳出循环

continue

continue 终止之后的运算,跳到循环开始下一个的循环

循环嵌套

函数

def FunctionName(param1, param2):
   ...
   return Outcome

默认参数

def FunctionName(param1, param2=12):
   ...
   return Outcome

复杂参数

def fun(id, *args, **kwargs):
    print("id = ", id)
    print("args = ", args)
    print("kwargs = ", kwargs)
    print("---------------------------------")

if __name__ == '__main__':
    fun(1,2,3,4)
    fun(1, a=1,b=2,c=3)
    fun('a','b','c', a=1,b=2,c=3)

    a = (1,2,3,4)
    b = {'a':1,'b':2,'c':3}

    fun(*a, **b)
id =  1
args =  (2, 3, 4)
kwargs =  {}
---------------------------------
id =  1
args =  ()
kwargs =  {'a': 1, 'c': 3, 'b': 2}
---------------------------------
id =  a
args =  ('b', 'c')
kwargs =  {'a': 1, 'c': 3, 'b': 2}
---------------------------------
id =  1
args =  (2, 3, 4)
kwargs =  {'a': 1, 'c': 3, 'b': 2}
---------------------------------

总结

*args是一个元组,而**kwargs是一个字典,同时,根据Python的要求,**kwargs必须放在*args后面。

这一特性非常适合编写含有大量参数的程序,比如使用字典,在程序中可以先判断该值是否存在,然后进行下一步的操作。判断字典值是否存在可以使用dict.has_key('key')进行判断。

惯用法

x = kwargs.pop('x', 0.5)
y = kwargs.pop('y', 0.98)

if ('horizontalalignment' not in kwargs) and ('ha' not in kwargs):
    kwargs['horizontalalignment'] = 'center'

Python 容器

Python 容器指的是以下四类数据结构。

  • 列表 list
  • 元组 turple
  • 字典 dict
  • 集合 set

列表和元组

列表和元组均可理解为数组,而且数组值的类型可以任意,或者不一致。二者的主要区别在于列表是可变的,元组是不可变的。

In [3]:
# 列表的创建

empty_list = []
empty_list = list()
In [4]:
# 列表的操作: list()

a = ('a1', 'a2', 3, 4, 'b12', [1,2,3])
b = list(a)
b
Out[4]:
['a1', 'a2', 3, 4, 'b12', [1, 2, 3]]
In [5]:
# 列表的操作: [offset]

b[0]
Out[5]:
'a1'
In [6]:
b[1:3]
Out[6]:
['a2', 3]
In [7]:
b[-1]
Out[7]:
[1, 2, 3]
In [8]:
# 列表的操作: 修改

b[3] = 'b3'
b
Out[8]:
['a1', 'a2', 3, 'b3', 'b12', [1, 2, 3]]
In [9]:
# 列表的操作: 切片 Slice
# [start:end:step]

b[1:6:2]
Out[9]:
['a2', 'b3', [1, 2, 3]]
In [10]:
b[::-2]
Out[10]:
[[1, 2, 3], 'b3', 'a2']
In [11]:
# 列表的操作: 尾部添加元素

b.append('append1')
b
Out[11]:
['a1', 'a2', 3, 'b3', 'b12', [1, 2, 3], 'append1']
In [12]:
# 列表的操作: 合并 extend, +=

b2 = [1,2,3]
b.extend(b2)
b
Out[12]:
['a1', 'a2', 3, 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3]
In [13]:
b += b2
b
Out[13]:
['a1', 'a2', 3, 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3, 1, 2, 3]
In [14]:
# 列表的操作:指定位置添加 insert

print(b)
b.insert(3, 'python3')
print(b)
['a1', 'a2', 3, 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3, 1, 2, 3]
['a1', 'a2', 3, 'python3', 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3, 1, 2, 3]
In [15]:
# 列表的操作: 指定位置删除 del

del b[3]
print(b)
['a1', 'a2', 3, 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3, 1, 2, 3]
In [16]:
# 列表的操作: 删除具有特定值的元素

print(b)
b.remove(3)
print(b)
['a1', 'a2', 3, 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3, 1, 2, 3]
['a1', 'a2', 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3, 1, 2, 3]
In [17]:
# 列表的操作: 获取并删除 pop

print(b)
pb = b.pop(1)
print(pb)
print(b)
['a1', 'a2', 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3, 1, 2, 3]
a2
['a1', 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3, 1, 2, 3]
In [18]:
# 列表的操作: 查询元素的位置 index

print(b)
print( b.index('append1') )
['a1', 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3, 1, 2, 3]
4
In [19]:
# 列表的操作: 判断是否在列表中 in

print(b)
print( 'append1' in b )
['a1', 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3, 1, 2, 3]
True
In [20]:
# 列表的操作: 值出现的次数

print(b)
print( b.count(2) )
['a1', 'b3', 'b12', [1, 2, 3], 'append1', 1, 2, 3, 1, 2, 3]
2
In [21]:
# 列表的操作: 转化为字符串

c = ['1', '2', '3', '4', '5', '6']
print(c)

','.join(c)
['1', '2', '3', '4', '5', '6']
Out[21]:
'1,2,3,4,5,6'
In [22]:
# 列表的操作: 排序

c = ['includes', 'several', 'open', 'source', 'development', 'environments', 'such', 'as']

# 副本排序 sorted

sorted_c = sorted(c)

print(c)
print(sorted_c)
['includes', 'several', 'open', 'source', 'development', 'environments', 'such', 'as']
['as', 'development', 'environments', 'includes', 'open', 'several', 'source', 'such']
In [23]:
# 原地排序 sort

c.sort()

print(c)
['as', 'development', 'environments', 'includes', 'open', 'several', 'source', 'such']
In [24]:
# 反序

c.sort(reverse=True)
print(c)
['such', 'source', 'several', 'open', 'includes', 'environments', 'development', 'as']
In [25]:
# 列表的操作: 列表长度

print(len(c))
8
In [26]:
# 列表的操作: 赋值, 复制

# 使用 = 进行赋值
# 使用 copy 进行复制

a = [1, 2, 3]
b = a
print(b)
a[1] = 1234
print("a", a)
print("b", b)
[1, 2, 3]
a [1, 1234, 3]
b [1, 1234, 3]
In [27]:
c = a.copy()
print(c)
[1, 1234, 3]

字典 dict

K-V

In [28]:
# 字典的操作: 创建 {}

empty_dict = {}
kv_dict = {
    "key": "this is a key",
    "value": 1234,
}

print(empty_dict)
print(kv_dict)
{}
{'key': 'this is a key', 'value': 1234}
In [29]:
# 字典的操作: 转化 dict()

s = [['a', 'aa'], ['b', 'bb']]
d = dict(s)
print(d)
{'a': 'aa', 'b': 'bb'}
In [30]:
# 字典的操作: 修改元素 [key]

kv_dict['key'] = 'kkkkkk'
print(kv_dict)
{'key': 'kkkkkk', 'value': 1234}
In [31]:
# 字典的操作:合并字典 update

other_dict = {
    "other" : 987654,
}

kv_dict.update(other_dict)
print(kv_dict)
{'key': 'kkkkkk', 'other': 987654, 'value': 1234}
In [32]:
# 字典的操作:删除指定键

del kv_dict['other']
print(kv_dict)
{'key': 'kkkkkk', 'value': 1234}
In [33]:
# 字典的操作:删除所有元素 clear

kv_dict.clear()
print(kv_dict)
{}
In [34]:
# 字典的操作:判断是否在字典中 in

kv_dict = {
    "key": "this is a key",
    "value": 1234,
}

print('value1' in kv_dict)
False
In [35]:
# 字典的操作:获取所有键 keys()

print(kv_dict.keys())

print(list(kv_dict.keys()))
dict_keys(['key', 'value'])
['key', 'value']
In [36]:
# 字典的操作:获取所有值 values()


print(list(kv_dict.values()))
['this is a key', 1234]
In [37]:
# 字典的操作:获取所有键值对 items


print(list(kv_dict.items()))
[('key', 'this is a key'), ('value', 1234)]

集合 set

set只有键,键不允许重复,支持集合的运算

In [38]:
# 集合的操作:创建 {} 或者 set()

odd = {1, 3, 5, 7, 9}
even = {0, 2, 4, 6, 8}

samset = set('letters')
print(samset)
{'s', 'l', 't', 'r', 'e'}
In [39]:
# 字典的操作:测试值是否存在 in

print(2 in odd)
False
In [40]:
# 字典的操作:交集 &

odd & even
Out[40]:
set()
In [41]:
# 字典的操作:并集 |

odd | even
Out[41]:
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
In [42]:
# 字典的操作:差集 - 或者 difference

odd - even
odd.difference(even)
Out[42]:
{1, 3, 5, 7, 9}
In [43]:
# 字典的操作:异或 ^(去掉仅在两个集合中出现一次)

a = {1, 2, 3}
b = {3, 4, 5}

a^b
Out[43]:
{1, 2, 4, 5}
In [44]:
# 字典的操作:是否为子集

a = {3}
b = {3, 4, 5}

a <= b

# 真子集 <

a < b
Out[44]:
True
In [45]:
# 字典的操作:超集

a >= b

a > b
Out[45]:
False

推导式

Python的推导式是一个具有Python风格的创建数据结构的方式,可以加速迭代,以少量的代码生成复杂的数据结构

列表推导式

[expression for item in iterable if condition]

In [46]:
# 生成偶数

a = [n for n in range(1,10) if n % 2 == 0]
print(a)
[2, 4, 6, 8]
In [47]:
# 生成数组

a = [(x, y) for x in range(1, 4) for y in range (1,5)]
print(a)
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4)]

字典推导式

[key:val for expression in iterable if condition]

In [48]:
# 

a = {k:v for k in range(1, 4) for v in range (6,9)}
print(a)
{1: 8, 2: 8, 3: 8}

Python 代码风格(PEP8)

Python Enhancement Proposal (PEP) 8 – Style Guide for Python Code

Python 增强提案定义了一系列的规范,PEP8 是代码风格的规范,可以 参考: http://pep8.org

  • 代码布局
  • 字符串引用
  • 表达式和语句中的空白
  • 注释
  • 版本
  • 命名

代码布局

缩进

  • 每级缩进使用4个空格
  • 参数尽量对齐
# Aligned with opening delimiter.
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

# More indentation included to distinguish this from the rest.
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

# Hanging indents should add a level.
foo = long_function_name(
    var_one, var_two,
    var_three, var_four)
# Arguments on first line forbidden when not using vertical alignment.
foo = long_function_name(var_one, var_two,
    var_three, var_four)

# Further indentation required as indentation is not distinguishable.
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)
  • if语句
# No extra indentation.
if (this_is_one_thing and
    that_is_another_thing):
    do_something()

# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
    that_is_another_thing):
    # Since both conditions are true, we can frobnicate.
    do_something()

# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
        and that_is_another_thing):
    do_something()
  • 长数组、元组
my_list = [
    1, 2, 3,
    4, 5, 6,
    ]
result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f',
    )
my_list = [
    1, 2, 3,
    4, 5, 6,
]
result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f',
)

Tab还是空格?

  • 推荐使用空格进行缩进
  • Python 2可以混用,但不推荐,可以使用 –t 选项进行检查
  • Python 3不允许混用

每行最大长度

  • 每行长度限制在 79 个字符以内
  • 一个推荐的换行方式是使用反斜杠
  • 逻辑运算符附近的换行最好在运算符之后

空行

  • 使用2个空行来分隔最高级的函数(function)和类(class)定义
  • 使用1个空行来分隔类中的方法(method)定义

源文件编码

  • Python核心发行版中的代码一支使用UTF-8(Python2使用ASCII)
  • 几种常见的编码声明方式
# -*- coding: utf-8 -*-

imports

  • imports应该分行写
  • imports应该写在代码文件的开头,位于模块注释和文档字符串之后,模块全局变量和常量声明之前
  • imports顺序,不同组之间使用空格隔开:
    • 标准库
    • 相关第三方
    • 本地库
  • 推荐使用绝对(absolue)imports,处理复杂包布局时,可以使用相对imports
  • 避免使用通配符imports,比如 from <module> import *
import mypkg.sibling

from subprocess import Popen, PIPE
from mypkg.sibling import example

from . import sibling
from .sibling import example

字符串引用

  • 在Python的世界,单引号和双引号是一样的,但不推荐混用,最好选择一种规则坚持使用。
  • 三引号字符串,使用双引号字符,即 “”” ,这样可以和 PEP 257的规则保持一致

表达式中的空白

一些痛点

  • 方括号、圆括号和花括号之
spam(ham[1], {eggs: 2})      # Yes

spam( ham[ 1 ], { eggs: 2 } )    # No
  • 逗号、分号和冒号之
if x == 4: print x, y; x, y = y, x            # Yes

if x == 4 : print x , y ; x , y = y , x        # No
  • 切片操作
# Yes
ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
ham[lower:upper], ham[lower:upper:], ham[lower::step]
ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]
# No
ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]
  • 函数调用
spam(1)      # Yes

spam (1)    # No
  • 切片左中括号前
dct['key'] = lst[index]      # Yes

dct ['key'] = lst [index]    # No
  • 赋值不需要进行对齐
x = 1                # Yes
y = 2
long_variable = 3

x             = 1        # No
y             = 2
long_variable = 3

其他建议

  • 二元运算符前后都使用一个空格
    • 赋值运算符 =
    • 增减运算符 +=, -=
    • 比较运算符 ==, <, >, !=, <>, <=, >=, in, not in, is, is not
    • 布尔运算符 and, or, not
  • 如果使用了优先级不同的运算符,优先级低的周围增加空白
i = i + 1                # Yes
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)

i=i+1                    # No
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
  • 函数参数中的 = 前后可以不留白
# Yes
def complex(real, imag=0.0):
    return magic(r=real, i=imag)

# No
def complex(real, imag = 0.0):
    return magic(r = real, i = imag)
  • 带注解的函数 -> 前后有空白,: 后面一个空白
# Yes
def munge(input: AnyStr): ...
def munge() -> AnyStr: ...

# No
def munge(input:AnyStr): ...
def munge()->PosInt: ...
  • 复合语句(多条语句放在一行中)一般不鼓励使

pep8工具

pip install pep8

Usage:

pep8 inputfile

In [52]:
!cat pep8_test.py
def Hello():
    a=[12,34,56]
    for i in a:
	print(a)
In [53]:
!pep8 pep8_test.py
pep8_test.py:2:6: E225 missing whitespace around operator
pep8_test.py:2:10: E231 missing whitespace after ','
pep8_test.py:2:13: E231 missing whitespace after ','
pep8_test.py:4:1: E101 indentation contains mixed spaces and tabs
pep8_test.py:4:1: W191 indentation contains tabs

Python 软件包管理

pip

Usage:
  pip <command> [options]

Commands:
  install                     Install packages.
  download                    Download packages.
  uninstall                   Uninstall packages.
  freeze                      Output installed packages in requirements format.
  list                        List installed packages.
  show                        Show information about installed packages.
  search                      Search PyPI for packages.
  wheel                       Build wheels from your requirements.
  hash                        Compute hashes of package archives.
  completion                  A helper command used for command completion
  help                        Show help for commands.

General Options:
  -h, --help                  Show help.
  --isolated                  Run pip in an isolated mode, ignoring environment variables and user configuration.
  -v, --verbose               Give more output. Option is additive, and can be used up to 3 times.
  -V, --version               Show version and exit.
  -q, --quiet                 Give less output.
  --log <path>                Path to a verbose appending log.
  --proxy <proxy>             Specify a proxy in the form [user:passwd@]proxy.server:port.
  --retries <retries>         Maximum number of retries each connection should attempt (default 5 times).
  --timeout <sec>             Set the socket timeout (default 15 seconds).
  --exists-action <action>    Default action when a path already exists: (s)witch, (i)gnore, (w)ipe, (b)ackup.
  --trusted-host <hostname>   Mark this host as trusted, even though it does not have valid or any HTTPS.
  --cert <path>               Path to alternate CA bundle.
  --client-cert <path>        Path to SSL client certificate, a single file containing the private key and the
                              certificate in PEM format.
  --cache-dir <dir>           Store the cache data in <dir>.
  --no-cache-dir              Disable the cache.
  --disable-pip-version-check
                              Don't periodically check PyPI to determine whether a new version of pip is available for
                              download. Implied with --no-index.

安装

pip install pkg

升级

pip install -U pkg

搜索

pip search pkg

列出已安装的包

pip list

Python 2 和 Python 3

In [49]:
%%HTML
<iframe width=100% height=600 src="https://pythonclock.org/" ></iframe>
  • Python 3 是升级版本,与 Python 2 部分不兼容
  • Python 2 仍有大量的用户,还有不少库与 Python 3 不兼容
  • Python 3 的性能比 Python 2 有很大提升
In [50]:
# Python2 和 Python3

from __future__ import (absolute_import, division,
                        print_function, unicode_literals)
In [51]:
# -*- coding: utf-8 -*-

from __future__ import (absolute_import, division,
                        print_function, unicode_literals)