變量
- 除法
>>> 9 / 3
3.0
>>> 10 // 3
3
- 字符串多個(gè)空行
print('''line1
line2
line3''')
list,tuple
-
list:可變數(shù)組
classmates = ['Michael', 'Bob', 'Tracy']
classmates[-1] #末尾元素
classmates.pop() #刪除末尾元素
classmates.pop(1) #刪除索引1元素
classmates[1] = "Chen" ##替代元素
classmates.insert(1,'Jack')
classmates.append('Bai')
-
tuple:不可變數(shù)組
classmates = ('Michael', 'Bob', 'Tracy')
t = (1,)
#只有一個(gè)元素時(shí)須加,
條件判斷
age = 3
if age >= 18:
print('your age is', age)
print('adult')
else:
print('your age is', age)
print('teenager')
":"代表后面縮進(jìn)的部分都是他的塊。
循環(huán)
- for x in ...: 遍歷
sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
sum = sum + x
print(sum)
- random()函數(shù):
>>> range(5)
[0, 1, 2, 3, 4]
- while
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
- break:在循環(huán)過程中直接退出循環(huán)
- continue:提前結(jié)束本輪循環(huán),并直接開始下一循環(huán)
字典
判斷key是否存在
- in
>>> 'Thomas' in d
False
- get
>>> d.get('Thomas') #返回None的時(shí)候,交互式命令行不顯示結(jié)果
>>> d.get('Thomas', -1) #如果key不存在,返回None或者指定的value
-1
基本操作
- 刪除key
>>> d.pop('Bob')
set:也是一組key的集合,但不存儲(chǔ)value。由于key不能重復(fù),所以,在set中,沒有重復(fù)的key
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}
函數(shù)
- 內(nèi)聯(lián)函數(shù):http://www.cottonclub.com.cn/UploadFiles/004.mp3
- 參數(shù)類型檢查:
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
函數(shù)參數(shù)
-
位置參數(shù)
def power(x):
-
默認(rèn)參數(shù)
def power(x, n=2): # power(5)相當(dāng)于power(5,2)
注意: 默認(rèn)參數(shù)必須指向不變對(duì)象
- 可變參數(shù):可變參數(shù)允許你傳入0個(gè)或任意個(gè)參數(shù),這些可變參數(shù)在函數(shù)調(diào)用時(shí)自動(dòng)組裝為一個(gè)tuple。
def calc(*numbers): #在函數(shù)內(nèi)部,參數(shù)numbers接收到的是一個(gè)tuple
sum = 0
for n in numbers:
sum = sum + n * n
return sum
calc(1, 2)
如果已經(jīng)有一個(gè)list或者tuple
>>> nums = [1, 2, 3]
>>> calc(*nums)
- 關(guān)鍵字參數(shù):關(guān)鍵字參數(shù)允許你傳入0個(gè)或任意個(gè)含參數(shù)名的參數(shù),這些關(guān)鍵字參數(shù)在函數(shù)內(nèi)部自動(dòng)組裝為一個(gè)dict。
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
如果已經(jīng)有一個(gè)dict
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
- 命名關(guān)鍵字參數(shù):如果要限制關(guān)鍵字參數(shù)的名字,就可以用命名關(guān)鍵字參數(shù)。
def person(name, age, *, city, job): #只接受city,job作為關(guān)鍵字參數(shù)
print(name, age, city, job)
如果函數(shù)定義中已經(jīng)有了一個(gè)可變參數(shù),后面跟著的命名關(guān)鍵字參數(shù)就不再需要一個(gè)特殊分隔符*了:
def person(name, age, *args, city, job):
print(name, age, args, city, job)
- 參數(shù)組合:參數(shù)定義的順序必須是:必選參數(shù)、默認(rèn)參數(shù)、可變參數(shù)、命名關(guān)鍵字參數(shù)和關(guān)鍵字參數(shù)。
使用args和*kw是Python的習(xí)慣寫法,當(dāng)然也可以用其他參數(shù)名,但最好使用習(xí)慣用法。
切片
L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
>>> L[:3]
['Michael', 'Sarah', 'Tracy']
>>> L[1:3]
['Sarah', 'Tracy']
>>> L[-2:]
['Bob', 'Jack']
>>> L[-2:-1]
['Bob']
tuple和字符串也可以使用。
>>> L[:10:2] 前10個(gè)數(shù),每兩個(gè)取一個(gè):
[0, 2, 4, 6, 8]
高級(jí)特性
迭代
dict迭代:默認(rèn)情況下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同時(shí)迭代key和value,可以用for k, v in d.items()。
其他語言中是通過下標(biāo)完成,如下
for (i=0; i<list.length; i++) {
n = list[i];
}
如果我們希望在python中使用,Python內(nèi)置的enumerate函數(shù)可以把一個(gè)list變成索引-元素對(duì),這樣就可以在for循環(huán)中同時(shí)迭代索引和元素本身:
>>> for i, value in enumerate(['A', 'B', 'C']):
... print(i, value)
...
0 A
1 B
2 C
以上形式,在python中較為常用。
>>> for x, y in [(1, 1), (2, 4), (3, 9)]:
... print(x, y)
...
1 1
2 4
3 9
列表生成式
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
生成器
將列表生成器變?yōu)樯善?/p>
>>> L = [x * x for x in range(10)]
>>> g = (x * x for x in range(10))
>>> next(g) #一個(gè)一個(gè)打印
>>> g = (x * x for x in range(10)) #循環(huán)打印
>>> for n in g:
... print(n)
...
將函數(shù)變?yōu)樯善鳎?/p>
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b #加入yield
a, b = b, a + b
n = n + 1
return 'done'
>>> for n in fib(6):
... print(n)
...
1
1
2
3
5
8
例子
def triangles():
n, L = 1, []
while True:
n, L = n+1, [1 if(i == len(L) or i == 0) else L[i - 1] + L[i] for i in range(len(L)+1)]
yield L
n = 0
for t in triangles():
print(t)
n = n + 1
if n == 10:
break
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
迭代器
- 可迭代對(duì)象Iterable:可以直接作用于for循環(huán)的對(duì)象統(tǒng)稱為可迭代對(duì)象。一類是集合數(shù)據(jù)類型,如list、tuple、dict、set、str等;一類是generator,包括生成器和帶yield的generator function。
可以使用isinstance()判斷一個(gè)對(duì)象是否是Iterable對(duì)象:
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
- 迭代器Iterator:可以被next()函數(shù)調(diào)用并不斷返回下一個(gè)值的對(duì)象稱為迭代器,表示的是一個(gè)數(shù)據(jù)流。
可以使用isinstance()判斷一個(gè)對(duì)象是否是Iterator對(duì)象:
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
- 把list、dict、str等Iterable變成Iterator可以使用iter()函數(shù):
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
函數(shù)式編程
- map:map()函數(shù)接收兩個(gè)參數(shù),一個(gè)是函數(shù),一個(gè)是Iterable,map將傳入的函數(shù)依次作用到序列的每個(gè)元素,并把結(jié)果作為新的Iterator返回。
>>> def f(x):
... return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r) #list()函數(shù)讓它把整個(gè)序列都計(jì)算出來并返回一個(gè)list。
[1, 4, 9, 16, 25, 36, 49, 64, 81]
- reduce:reduce把一個(gè)函數(shù)作用在一個(gè)序列[x1, x2, x3, ...]上,這個(gè)函數(shù)必須接收兩個(gè)參數(shù),reduce把結(jié)果繼續(xù)和序列的下一個(gè)元素做累積計(jì)算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
將str變?yōu)閕nt并計(jì)算
>>> from functools import reduce
>>> def fn(x, y):
... return x * 10 + y
...
>>> def char2num(s):
... return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
...
>>> reduce(fn, map(char2num, '13579'))
13579
- filter:主要用于過濾,把傳入的函數(shù)依次作用于每個(gè)元素,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素。
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 結(jié)果: [1, 5, 9, 15]
- sort:除普通排序外,它還可以接收一個(gè)key函數(shù)來實(shí)現(xiàn)自定義的排序,例如按絕對(duì)值大小排序。
>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
return t[0]
L2=sorted(L,key=by_name)
key=str.lower 忽略大小寫 reverse=True 反向排序
匿名函數(shù)
lambda x: x * x
**等價(jià)于下列內(nèi)容**
def f(x):
return x * x
裝飾器
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log #把@log放到now()函數(shù)的定義處,相當(dāng)于執(zhí)行了語句:now = log(now)
def now():
print('2015-3')
now()
$ python a.py
call now():
2015-3
帶參數(shù)的decorator
import functools
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
@log('execute') #相當(dāng)于>>> now = log('execute')(now)
偏函數(shù)
ef int2(x, base=2):
return int(x, base)
##把一個(gè)函數(shù)的某些參數(shù)給固定住(也就是設(shè)置默認(rèn)值),返回一個(gè)新的函數(shù),調(diào)用這個(gè)新函數(shù)會(huì)更簡單。
>>> import functools
>>> int2 = functools.partial(int, base=2)
內(nèi)置函數(shù)
https://docs.python.org/3/library/functions.html
模塊
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' a test module ' #文檔注釋
__author__ = 'Michael Liao'
import sys
def test():
args = sys.argv
if len(args)==1:
print('Hello, world!')
elif len(args)==2:
print('Hello, %s!' % args[1])
else:
print('Too many arguments!')
if __name__=='__main__': #當(dāng)我們?cè)诿钚羞\(yùn)行hello模塊文件時(shí),Python解釋器把一個(gè)特殊變量__name__置為__main__,而如果在其他地方導(dǎo)入該hello模塊時(shí),if判斷將失敗,因此,這種if測(cè)試可以讓一個(gè)模塊通過命令行運(yùn)行時(shí)執(zhí)行一些額外的代碼,最常見的就是運(yùn)行測(cè)試。
test()
使用域
- 公開的,可以被直接引用:比如:abc,x123,PI等;
- 特殊的:類似xxx這樣的變量是特殊變量,可以被直接引用,但是有特殊用途,比如上面的author,name就是特殊變量。
- 非公開的:類似_xxx和__xxx這樣的函數(shù)或變量就是非公開的(private),不應(yīng)該被直接引用,比如_abc,__abc等。
面向?qū)ο缶幊?/h3>
訪問限制
class Student(object):
"""docstring for Student."""
def __init__(self, name, score):
self.__name = name #__name私有變量
self.__score = score
def set_score(self, score): #從外部修改私有變量,
self._score = score
def set_name(self, name):
self._name =name
def get_score(self): #從外部訪問獲取私有變量
return self.__score
def get_name(self):
return self.__name
def print_score(self):
print('%s:%s' % (self._name,self._score))
Bai = Student('Bai', 100)
BaiName = Bai.get_name()
獲取對(duì)象信息
- type
>>> import types
>>> def fn():
... pass
...
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True
>>> type('abc')==str
True
>>> type(123)==int
True
-
isinstance:相比較type,更能反映繼承關(guān)系,同時(shí)可以判斷是否是某些類型中的一種
>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))
True
-
dir:獲得一個(gè)對(duì)象的所有屬性和方法。
>>> dir('ABC')
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
class Student(object):
"""docstring for Student."""
def __init__(self, name, score):
self.__name = name #__name私有變量
self.__score = score
def set_score(self, score): #從外部修改私有變量,
self._score = score
def set_name(self, name):
self._name =name
def get_score(self): #從外部訪問獲取私有變量
return self.__score
def get_name(self):
return self.__name
def print_score(self):
print('%s:%s' % (self._name,self._score))
Bai = Student('Bai', 100)
BaiName = Bai.get_name()
>>> import types
>>> def fn():
... pass
...
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True
>>> type('abc')==str
True
>>> type(123)==int
True
>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))
True
>>> dir('ABC')
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
類似xxx的屬性和方法在Python中都是有特殊用途的,下列就是等價(jià)的
>>> len('ABC')
3
>>> 'ABC'.__len__()
3
配合getattr()、setattr()以及hasattr(),我們可以直接操作一個(gè)對(duì)象的狀態(tài)。
>>> class MyObject(object):
... def __init__(self):
... self.x = 9
... def power(self):
... return self.x * self.x
...
>>> obj = MyObject()
>>> hasattr(obj, 'x') # 有屬性'x'嗎?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有屬性'y'嗎?
False
>>> setattr(obj, 'y', 19) # 設(shè)置一個(gè)屬性'y'
>>> hasattr(obj, 'y') # 有屬性'y'嗎?
True
>>> getattr(obj, 'y') # 獲取屬性'y'
19
>>> obj.y # 獲取屬性'y'
19
##也可以獲取方法
>>> getattr(obj, 'power') # 獲取屬性'power'
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
- slots:想要限制實(shí)例的屬性.對(duì)繼承的無效。
class Student(object):
__slots__ = ('name', 'age') # 用tuple定義允許綁定的屬性名稱
>>> s = Student() # 創(chuàng)建新的實(shí)例
>>> s.name = 'Michael' # 綁定屬性'name'
>>> s.age = 25 # 綁定屬性'age'
>>> s.score = 99 # 綁定屬性'score'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'
-@property:綁定屬性時(shí),如果我們直接把屬性暴露出去,雖然寫起來很簡單,但是,沒辦法檢查參數(shù),導(dǎo)致可以把成績隨便改。Python內(nèi)置的@property裝飾器就是負(fù)責(zé)把一個(gè)方法變成屬性調(diào)用。
class Student(object):
def get_score(self):
return self._score
def set_score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
上述寫法過于復(fù)雜,所以需要簡化
class Student(object):
#可讀可寫
@property
def birth(self):
return self._birth
@birth.setter
def birth(self, value):
self._birth = value
#只可寫
@property
def age(self):
return 2015 - self._birth
- str 和 repr:用于優(yōu)化打印結(jié)果
class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name=%s)' % self.name
__repr__ = __str__
# __str__部分
>>> print(Student('Michael'))
Student object (name: Michael)
# __repr__部分
>>> s = Student('Michael')
>>> s
<__main__.Student object at 0x109afb310>
- getattr:如果一個(gè)類沒有相應(yīng)屬性,那么還可以寫一個(gè)getattr()方法,動(dòng)態(tài)返回一個(gè)屬性。一般默認(rèn)返回None.(只有在沒有找到屬性的情況下,才調(diào)用getattr)
class Student(object):
def __init__(self):
self.name = 'Michael'
def __getattr__(self, attr):
if attr=='score':
return 99
- 枚舉
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
for name, member in Month.__members__.items():
print(name, '=>', member, ',', member.value) #value默認(rèn)從1開始
如果需要更精確地控制枚舉類型,可以從Enum派生出自定義類:
from enum import Enum, unique
@unique # @unique裝飾器可以幫助我們檢查保證沒有重復(fù)值。
class Weekday(Enum):
Sun = 0 # Sun的value被設(shè)定為0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
元類
- type:函數(shù)既可以返回一個(gè)對(duì)象的類型,又可以創(chuàng)建出新的類型。我們說class的定義是運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建的,而創(chuàng)建class的方法就是使用type()函數(shù)。
>>> def fn(self, name='world'): # 先定義函數(shù)
... print('Hello, %s.' % name)
...
>>> Hello = type('Hello', (object,), dict(hello=fn)) # 創(chuàng)建Hello class
>>> h = Hello()
>>> h.hello()
Hello, world.
>>> print(type(Hello))
<class 'type'>
>>> print(type(h))
<class '__main__.Hello'>
要?jiǎng)?chuàng)建一個(gè)class對(duì)象,type()函數(shù)依次傳入3個(gè)參數(shù):
- class的名稱;
- 繼承的父類集合,注意Python支持多重繼承,如果只有一個(gè)父類,別忘了tuple的單元素寫法;
本筆記參考 Linux探索之旅
- class的方法名稱與函數(shù)綁定,這里我們把函數(shù)fn綁定到方法名hello上。