目录

注释

文档符号

“““与’’’

"""
这是一个模块,这个模块什么都不处理
"""
def get_name(index):
    '''获取名字
    
    :arg index: 名字索引
    '''
    names = {1:'tsing',2:'chan'}
    return names[index]

常用内建函数

  • type 内建函数 可以知道任何变量的数据类型
  • len 内建函数 可以知道任意序列类型数据的长度

类型-运算-输出

True与False

在python中返回使用真值,需要首字母大写

不能使用true和false

而是True和False

判断循环语句注意:

if a > 10:
#
elif a > 8:
#
else:
#

元组封装和拆封

data = ("a","b")
_a,_b = data    #输出_a值为a,

求余、求整

14 % 4  #2
14 / 4  #3.5
14 // 4 #3
divmod(15,2) ## 取整+取余,相当于15//2,15%2 得到 (7,1)

平方

n**2

逻辑运算符号

关系运算可以通过逻辑运算符 and 和 or 组合,比较的结果可以用 not 来取反意。逻辑运算符的优先级又低于关系运算符,在它们之中,not 具有最高的优先级,or 优先级最低,所以 A and not B or C 等于 (A and (not B)) or C。当然,括号也可以用于比较表达式。

2>1 and not 3>5 or 4 #True

强制转换类型

int()
float()
str()

右边表达式

Python 中赋值语句执行时会先对赋值运算符右边的表达式求值,然后将这个值赋值给左边的变量。

a,b = b,a+b

format

print("zzz{:2d}zzz{:5.2f}".format(12,12345.10))
# zzz12zzz12345.10

print

默认情况下,print() 除了打印你提供的字符串之外,还会打印一个换行符,所以每调用一次 print() 就会换一次行.

可以通过 print() 的另一个参数 end 来替换这个换行符.

print(a,end=" ")
print("#" * 20)
####################

列表

列表

它可以写作中括号之间的一列逗号分隔的值。列表的元素不必是同一类型

a = [1,23,4,5,"out","in"]
  • 与php相同地方

与php数组定义类似,使用方式也类似

  • 截取子列表负数索引

    截取类似php的slice

    可以使用负数索引,可以直接切割

    a[-1]   # "in"
    a[3]    # "in"
      
    a[0:2]  #从0位置开始取长度2的子列表
    a[0:-2]   #如果为负数,表示从0位置取到倒数第2个 
    
  • 截取步长

    a[0::2] #从0位置开始每隔2个元素取值
    
  • 列表连接合并

    类似于php的array_merge

    a = [1,2,3]
    b = [4,5]
    c = a + b #[1,2,3,4,5]
    
  • 切片赋值与清空

    a = [1,2,3,4,5,6]
    a[2:3] = [3,2] #[1,3,2,4,5,6]
    a[2:3] = [] #[1,4,5,6]
      
    
  • 判断值是否在列表

    a = [,1,2,3]
    if 1 in a:
        print('yes')
    else:
        print("false")
      
    
  • 判断列表

    a = []
    if a:
        print("not empty")
    else:
        print("empty")
    

循环遍历

for

```
a = [1,2,3]
for i in a
    print(i)
```

for中使用enumerate

如你想在遍历列表或任何序列类型的同时获得元素索引值,可以使用enumerate

for i,j in enumerate(a):
    print(i,j)

for中使用zip

你也许需用同时遍历两个序列类型,你可以使用zpi函数

a = ["a",'b']
b = ['apple','banana']

for _a,_b in zip(a,b):
    print("{} is {}".format(_a,_b))
    
#a is apple
#b is banana

range()函数

生成一个等差数列不是一个列表

```
a = range(1,15,2)   #第一个数1,最大不超过15,以2递增
list(a)
#[1, 3, 5, 7, 9, 11, 13]    
```

数据结构

列表

可以看做是其他语言的非键值对数组,允许不同类型的元素存在。常使用[]进行标识。

  • a.append(“a”) 添加元素到尾端
  • a.insert(1,“a”) 添加元素到任何位置
  • a.count(“a”) 返回列表中定值为"a"的元素
  • a.remove(“a”) 删除列表中定值为a的元素
  • a.reverse() 翻转列表
  • a.extend(b) 列表b扩展合并到列表a,末尾追加
  • a.sort() 按元素值给列表排序,前提是元素可排序
  • del 关键字非方法,删除指定位置(key)的元素 # del a[1]
  • a.pop(0) 将列表第1个元素弹出 栈:lifo, last in first out 队列:fifo,first in first out
  • 列表推导式
a = [1,2,3]
y = [x*2 for x in a]
z = [x-1 for x in[x**2 for x in a]]
#y :[2,4,6]
#z :[0,3,8]

元组

元组是由数个逗号分割的 (不一定是字符串) 组成。除了逗号外,也常使用()来标识。

a = 'apple','banana','city','decimal'
b = 1,2,3,4

元组可以像列表一样进行for循环遍历。

  • 元组的拆封
data = ('a','b')
_a,_b = data
#_a:a,_b:b
x,y = divmod(15,2)
#x:7 y:1
  • 创建一个元素的元组 要创建只含有一个元素的元组,在值后面跟一个逗号。(因为元组是通过逗号来分割的,机器只认这个)
a = (12,)
b = 12,

集合

集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。常使用{}来标识。

集合支持并集、交集、差集、对称差集等数学运算。

  • set函数 对字符串转换成无重复元素的集合
a = set('chinese')
#a = {'s','i','h','e','n','c'} ,这里输出是无序的

  • 常用集合操作
b = set('children')
a-b  #求a有b没有的元素
b-a  #反之
a|b  #在a或在b中的元素
a&b  #在a且在b中的元素
a^b  #在a或b中,但不同时存在的元素
  • a.pop() 随机弹出并删除一个元素
  • a.add(22)

字典

字典是无序的键值对(key:value)集合,同一个字典内的键必须是唯一的。常使用{}标识,可以参考json串。

data = {"a":"apple",'b':"banner"}
  • del 关键字删除元素
del data['a']
  • in 同样使用in来判断元素值是否在字典中
  • dinct() 可以从包含键值对的元组中创建字典
a = dinct((("a","apple"),("b","banner")));
#{"a":"apple","b":"banner"}
  • data.items()遍历字典
for x, y in data.items():
    print("{} uses {}".format(x, y))
  • 索引建最佳方式

不建议直接使用 data[index],除非你确定有index存在。 否则建议:

data.get(index,0) # 如果键不存在,会返回默认值

字符串对象

注意

  • \n \t等转义

和php脚本相反,python的转义符只有在单引号'‘里才有效果,在双引号里”\n"直接显示转义符号

a = 'a\nb'  
#a
#b
a = "a\nb"
#a\nb
  • 三对引号/文档字符串

“““或’’’

a = '''
a     
     b
     c'''
print(a)     
#a     
#     b
#     c
  • 字符串可以当做列表来使用
a = 'abcde'
print(a[::1])
#abcde
print(a[::2])
#ace

内建方法

  • a.title() 返回首字母大写字符串
  • a.upper() 返回全部字母大写
  • a.lower() 返回全小写
  • a.swapcase() 返回大小写置换,大写的字符变小写,反之
  • a.isalnum() 检查字符是否只有字母和数字
  • a.isalpha() 检查字符中只有字母
  • isdigit 检查全数字
  • islower 检查是否小写
  • istitle 检查是否标题样式字符串
  • isupper 检查是否全大写
  • split 分割任意字符,返回列表
  • “-".join(list) 使用指定字符连接多个字符串
"-".join("we are chinese".split())
#we-are-chinese
  • strip 去除收尾指定字符,类似于php的trim,默认去除空格与换行,支持lstrip和rstrip
  • find 搜索字符串里的文本或子字符串,没有找到返回-1
  • startwith 检查是否以指定字符串开头
  • endwith 检查是否以指定字符串结尾
  • a.count('\t’) a中有多少tab

格式化操作符

%

print("the name is %s.%d years old" % ('jm',4))
#the name is jm.4 years old

函数

__name__

__name__这个系统变量显示了当前模块执行过程中的名称,如果当前程序运行在这个模块中,name 的名称就是__main__如果不是,则为这个模块的名称。

局部变量和全局变量

如果你使用过java或php这些语言,基本差不多

和php相似的是,提供了关键字:global,可以在函数或局部模块中声明该变量是否全局变量

a = 9
def echome():
    global a
    a = 100    
    print(a)
print(a)    
echome()
print(a)
#9
#100  声明a为全局变量,但又被重新赋值
#100  全局变量在函数中已经被更改
#通过global声明后,在函数echome中才不会出现a未定义的问题

默认参数

与php脚本语言的函数默认参数值一样,可以预置默认值,但要注意的是传参是列表、字典等数据结构时,和php引用传参,会改变参数变量的值


def echome(a,b=1):
    print(a,b)

def echome(a,b=[]):
    b.append(a)
#如果b是个列表结构,则后续调用函数echome时,b不会一直是空列表,而是会累计元素

关键字参数

有时函数中会有多个默认参数,在调用函数时,需要跳过第1个默认参数设置,直接设置第二个默认参数,这就有了关键字参数

def echome(a,b=1,c=2):
    print(a,b,c)

echome(0,c=3)
#指定关键字参数c传值为3,b仍然使用默认参数值

文档字符串

前面我们说三对引号 "”” 或 '’’

高阶函数

参考js的回调函数、php的可变函数和匿名函数

通俗地说:允许函数传参时,参数是另一个函数

  • 内建函数map,就是高阶函数
list = [1,2,3]
def square(num):
    return num*num
print(list(map(square,list)))

list函数将元组转换成列表

文件读写

打开文件

open(file,mode)
#返回文件对象

关闭文件

fobj.close()
#确保显示关闭打开的每个文件

读取文件

  • 读取整个文件
fobj.read(size)
#size 默认空,读取整个文件
#注意:read二次调用的时候,返回空,官方说已经读取过整个文件
  • 读取文件的一行
fobj.readline()
#
  • 读取所有行到一个列表
fobj.readlines()
  • 写文件
ff = opne("a.txt",'w')
ff.write("tsing")
ff.close()

with语句

在实际情况中,我们应该尝试使用 with 语句处理文件对象,它会在文件用完后会自动关闭,就算发生异常也没关系。它是 try-finally 块的简写:

with open("sample.txt") as fileobj:
    lines = fileobj.reads()
    for line in lines:
        print(line,end='')
import os
path = '/proc/cpuinfo'
if os.path.exists(path):
    with open(path) as cpuobj:
        for line in cpuinfo:
            print(line,end='')
else:
    print("get cpuinfo failed.")

异常

捕获异常

try:

except:

finally:

with 是 try-finally的简写

raise 抛出异常

try:
    raise ValueError
except:
    ##

定义

关键字:class

在类的声明中,可以写任何的python语句,包括函数。

class myclass(parentClass):
    i=1
    def mymethod():
        return 1+1
        

实例化

类的实例化使用函数符号

只要把类对象看做是一个返回新的类实例的无参函数即可。

x = myclass()
#创建一个空的新的类实例,并将该对象赋给变量x

如果我们需要根据不同需要创建不同状态的相同类的不同实例时,需要使用到构造函数__init__

class myclass():
    def __init__(self,_b,_c):
        self.b = _b
        self.c = _c

x = myclass(1,2)        

print(x.b)
# 1
print(x.c)
# 2

继承

与大部分面向对象语言一样,继承都需要构造器重写,并调用父级构造器,python构造器__init__的第一个参数必须是类自己self

初始类继承于object

class Person(object):
    """
    返回具有给定名称的 Person 对象
    """

    def __init__(self, name):
        self.name = name

    def get_details(self):
        """
        返回包含人名的字符串
        """
        return self.name


class Student(Person):
    """
    返回 Student 对象,采用 name, branch, year 3 个参数
    """

    def __init__(self, name, branch, year):
        Person.__init__(self, name)
        self.branch = branch
        self.year = year

    def get_details(self):
        """
        返回包含学生具体信息的字符串
        """
        return "{} studies {} and is in {} year.".format(self.name, self.branch, self.year)


class Teacher(Person):
    """
    返回 Teacher 对象,采用字符串列表作为参数
    """
    def __init__(self, name, papers):
        Person.__init__(self, name)
        self.papers = papers

    def get_details(self):
        return "{} teaches {}".format(self.name, ','.join(self.papers))


person1 = Person('Sachin')
student1 = Student('Kushal', 'CSE', 2005)
teacher1 = Teacher('Prashad', ['C', 'C++'])

print(person1.get_details())
print(student1.get_details())
print(teacher1.get_details())

多继承

class class1(object):
    #
class class2(object):
    #
class myclass(class1,class2):
    def __init__(self):
        class1.__init__(self)
        class2.__init__(self)
    

删除对象

del x

del 实际上使对象的引用计数减少一,当对象的引用计数变成零的时候,垃圾回收器会删除这个对象。

属性读取

在 Python 里请不要使用属性(attributes)读取方法(getters 和 setters)。如果你之前学过其它语言(比如 java\php),你可能会想要在你的类里面定义属性读取方法。请不要这样做,直接使用属性就可以了,就像下面这样:

这个对于java\php的开发者一下子可能无法理解

class myclass(object):
    def __init__(self):
        self.name = 'tsing'
        
x = myclass()
print(x.name)   #不用在类中声明属性set/get方法,再通过set/get设置


装饰器

为了解决set和get的问题,python引入装饰器。

你可能想要更精确的调整控制属性访问权限,你可以使用 @property 装饰器,@property 装饰器就是负责把一个方法变成属性调用的。

注意:amount.setter 的声明

class Account(object):
    """账号类,
    amount 是美元金额.
    """
    def __init__(self, rate):
        self.__amt = 0
        self.rate = rate

    @property
    def amount(self):
        """账号余额(美元)"""
        return self.__amt

    @property
    def cny(self):
        """账号余额(人民币)"""
        return self.__amt * self.rate

    @amount.setter
    def amount(self, value):
        if value < 0:
            print("Sorry, no negative amount in the account.")
            return
        self.__amt = value

if __name__ == '__main__':
    acc = Account(6.6)
    acc.amount = 20
    print("Dollar amount:", acc.amount)
    print("In CNY:", acc.cny)
    acc.amount = -100
    print("Dollar amount:", acc.amount)

模块和包

模块定义

模块是包括 Python 定义和声明的文件。文件名就是模块名加上 .py 后缀。

例子胜过描述:

创建一个bars.py文件:

定义一个模块bars及定义3个函数

"""
Bars Module
============
这是一个打印不同分割线的示例模块
"""
def starbar(num):
    """打印 * 分割线

    :arg num: 线长
    """
    print('*' * num)

def hashbar(num):
    """打印 # 分割线

    :arg num: 线长
    """
    print('#' * num)

def simplebar(num):
    """打印 - 分割线

    :arg num: 线长
    """
    print('-' * num)

模块导入

导入模块:

import bars
bars.starbar(10)
# **********

也可以导入模块中指定函数:

注意:没有模块bars变量

from bars import starbar,hashbar
starbar(5)

默认模块

查看默认模块列表

>>> help()
>>> modules
>>> help(str) #查看str对象帮助文档

含有 init.py 文件的目录可以用来作为一个包,目录里的所有 .py 文件都是这个包的子模块。

init.py 最简单的方式就是放空,当然也可以自定义执行包的初始化代码。

比如有个处理音频的包:

sound/                          Top-level package
      __init__.py               Initialize the sound package
      formats/                  Subpackage for file format conversions
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  Subpackage for sound effects
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  Subpackage for filters
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

包的使用

用户可以每次只导入包里的特定模块,例如:

import sound.effects.echo

这样就导入了 sound.effects.echo 子模块。它必需通过完整的名称来引用:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

导入包时有一个可以选择的方式:

from sound.effects import echo

这样就加载了 echo 子模块,并且使得它在没有包前缀的情况下也可以使用,所以它可以如下方式调用:

echo.echofilter(input, output, delay=0.7, atten=4)

还有另一种变体用于直接导入函数或变量:

from sound.effects.echo import echofilter

这样就又一次加载了 echo 子模块,但这样就可以直接调用它的 echofilter() 函数:

echofilter(input, output, delay=0.7, atten=4)

包内引用

安装第三方模块

Requests 是一个第三方 Python 模块。

首先安装pip3

sudo apt-get update
sudo apt-get install python3-pip

然后用pip3安装requests

sudo pip3 install requests

查看已安装第三方模块

sudo pip3 list

collections 集合类模块

Counter

most_common() 方法返回最常见的元素及其计数,顺序为最常见到最少。

from collections import Counter
Counter("asdkfhajshfdkjashdf").most_common(3)

defaultdict

namedtuple

迭代器、生成器、装饰器、闭包

装饰器

给add函数,额外装饰处理

关键词:*args **kwargs 回调函数

def mydecorator(func):
    def wrapper(*args,**kwargs):
        print("before call")
        res = func(*args,**kwargs)
        print("after call")
        return res 
    return wrapper
         
@mydecorator
def add(a,b):
    return a+b 
num = add(1,3)
print(num)    

系统模块

os

模块提供了与操作系统相关的功能。

大部分类unix系统的命令都有相应方法:

os.chidir("/tmp")
os.system("mkdir today")

glob 文件通配符

import glob
glob.glob('*.py')
#['1.py','2.py']

sys 命令行参数

import sys
sys.exit(1) #退出脚本
sys.argv #获取脚本参数列表,和php脚本一样第一个参数为脚本文件名,后续参数为输入参数

如在linux:

python3 ./index.py "tsing" "real"

则sys.argv列表有三个值:

argv[0]:

./  index.py,

argv[1]:

tsing

argv[2]:

real

sys.stdin stdout stderr

re 字符串正则匹配

import re
re.findall(r'\bf[a-z]*','which foot or hand fell fastest')

数学 math

import math
math.cos(math.pi/4.0)
math.log(1024,2) #10

随机数 random

import random
random.choice([1,2,3]) # 1
random.random() #0.1716166161
random.randrange(6) #从1~6选一个整数

日期和时间 datetime

from datetime import date
now = date.today()
now.strftime("%m-%d-%y")
birthdayy = date(1990,1,1)
age = now - birthday
age.days

数据压缩

zlib,gzip,bz2,lzma,zipfile,tarfile

timeit 性能度量

>>> from timeit import Timer
>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
0.57535828626024577
>>> Timer('a,b = b,a', 'a=1; b=2').timeit()
0.54962537085770791

string

threading 多线程

logging 日志

import logging
logging.debug('Debugging information')
logging.info('Informational message')
logging.warning('Warning:config file %s not found', 'server.conf')
logging.error('Error occurred')
logging.critical('Critical error -- shutting down')

decimal 十进制浮点数计算

列表工具

array

collections

unix环境TAB补全

首先创建一个文件:~/.pythonrc ,文件内写入如下内容:

import rlcompleter, readline
readline.parse_and_bind('tab: complete')


history_file = os.path.expanduser('~/.python_history')
readline.read_history_file(history_file)

import atexit
atexit.register(readline.write_history_file, history_file)

下一步在 ~/.bashrc 文件中设置 PYTHONSTARTUP 环境变量指向这个文件:

$ export PYTHONSTARTUP=~/.pythonrc

现在,从今以后每当你打开 bash shell,你将会有 TAB 补全和 Python 解释器中代码输入的历史记录。

要在当前 shell 中使用,source 这个 bashrc 文件。

$ source ~/.bashrc

虚拟环境virtualenv

sudo pip3 install virtualenv

mkdir virtual
cd virtual
#创建环境
virtualenv virt1
#激活环境
source virt1/bin/activate
#关闭虚拟环境
deactivate

可以再创建另一个虚拟环境,两个虚拟环境安装不同模块,进行A/B环境测试

测试

范例 fact.py

import sys

def fact(n):
    """
    阶乘函数

    :arg n: 数字
    :returns: n 的阶乘

    """
    if n == 0:
        return 1
    return n * fact(n -1)

def div(n):
    """
    只是做除法
    """
    res = 10 / n
    return res


def main(n):
    res = fact(n)
    print(res)

if __name__ == '__main__':
    if len(sys.argv) > 1:
        main(int(sys.argv[1]))

测试用例 fact_test.py

import unittest
from fact import fact

class TestFact(unittest.TestCase):
    """
    我们的基本测试类
    """

    def test_fact(self):
        """
        实际测试
        任何以 `test_` 开头的方法都被视作测试用例
        """
        res = fact(5)
        self.assertEqual(res, 120)


if __name__ == '__main__':
    unittest.main()
    
#测试结果

python3 fact_test.py

.
----------------------
Ran 1 test in 0.003s

OK

assert语句

|Method|Checks that|New in|
|------ | ---- | ----- |
|assertEqual(a, b)|	a == b|	
|assertNotEqual(a, b)|	a != b	|
|assertTrue(x)|	bool(x) is True	|
|assertFalse(x)|	bool(x) is False|	
|assertIs(a, b)|	a is b|	2.7
|assertIsNot(a, b)|	a is not b|	2.7
|assertIsNone(x)|	x is None|	2.7
|assertIsNotNone(x)|	x is not None|	2.7
|assertIn(a, b)|	a in b|	2.7
|assertNotIn(a, b)|	a not in b|	2.7
|assertIsInstance(a, b)|	isinstance(a, b)|	|2.7
|assertNotIsInstance(a, b)|	not |isinstance(a, b)|	|2.7

疑问

  • 列表、元组、集合的方法是通用的吗?比如add、pop,含义一样吗?

不方便

  • 类、模块、函数相关注释不像java、php、js直观
  • 类中属性set与get使用装饰器方式,不方便编写及理解