-
python入門
在本章中你將
學(xué)習(xí)到python語法與編碼約定
了解到函數(shù)式編程與面向?qū)ο缶幊? 學(xué)習(xí)如何編寫裝飾器
了解python類多繼承的MRO算法
-
The Zen of Python
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
-
數(shù)據(jù)模型
在Python中數(shù)據(jù)被抽象成對象,Python程序中的所有數(shù)據(jù)都可以表示為對象或?qū)ο笾g的關(guān)系。 每個(gè)對象都由3個(gè)部分組成:
- identity,一旦被創(chuàng)建,就不會(huì)改變了,表示對象在內(nèi)存中的地址。
- type,對象的數(shù)據(jù)類型決定了對象支持的操作,以及value可變性,如numbers, strings and tuples 是可變類型, 而dictionaries
,lists是不可變的)。- value,表示對象的實(shí)際值。
Pytho常見數(shù)據(jù)類型可以分為:
- None(真值為False)
- Numbers(int,float,bool,complex)
- Sequences(可變: list | 不可變: str,unicode,tuple)
- Sets(set)
- Mappings(dict)
-
基礎(chǔ)語法
關(guān)鍵字
and del from not while
as elif global or with
assert else if pass yield
break except import print
class exec in raise
continue finally is return
def for lambda try
基本語法與約定
# 導(dǎo)入包
import scrapy as alias_name # 導(dǎo)入了命名空間scrapy 取別名
訪問屬性時(shí)候必須帶上命名空間
from __future__ import print_function # 直接將公共的屬性引入當(dāng)前命名空間 直接使用屬性名稱訪問
from xxxx import a,b,c 導(dǎo)入多個(gè)包
__import__() 使用內(nèi)置函數(shù)導(dǎo)入包
# 命名約定
所謂”內(nèi)部(Internal)”表示僅模塊內(nèi)可用, 或者, 在類內(nèi)是保護(hù)或私有的.
用單下劃線(_)開頭表示模塊變量或函數(shù)是protected的(使用import * from時(shí)不會(huì)包含).
用雙下劃線(__)開頭的實(shí)例變量或方法表示類內(nèi)私有.
將相關(guān)的類和頂級函數(shù)放在同一個(gè)模塊里. 不像Java, 沒必要限制一個(gè)類一個(gè)模塊.
對類名使用大寫字母開頭的單詞(如CapWords, 即Pascal風(fēng)格), 但是模塊名應(yīng)該用小寫加下劃線的方式(如lower_with_under.py). 盡管已經(jīng)有很多現(xiàn)存的模塊使用類似于CapWords.py這樣的命名, 但現(xiàn)在已經(jīng)不鼓勵(lì)這樣做, 因?yàn)槿绻K名碰巧和類名一致, 這會(huì)讓人困擾.
類命名采取CamelCase駝峰法,方法采用snake_case
數(shù)據(jù)類型
# -*- coding:utf-8 -*-
from __future__ import print_function
print(type(1))
print(type(999999999999))
print(type(0.1))
print(type(True))
print(type('a'))
print(type("hello world"))
print(type([1, 1, 2, 3]))
print(type({1, 2, 3}))
print(type({1: 'a', 2: 'b'}))
print(type((1, 'a', "abc")))
# 枚舉類型
from enum import Enum,unique
TimeUnit = Enum("TimeUnit", ("YEAR", "MONTH", "DAY", "HOUR", "MINUTE", "SECOND", "MILLS", "NANO"))
for unit, v in TimeUnit.__members__.items():
print(unit, ":", v.value)
@unique # 驗(yàn)證value 值唯一
class SomeType(Enum):
A = "a"
B = "b"
C = "c"
print(SomeType.A.value)
print(SomeType.B)
控制結(jié)構(gòu)
# 條件判斷
if <條件判斷1>:
<執(zhí)行1>
elif <條件判斷2>:
<執(zhí)行2>
elif <條件判斷3>:
<執(zhí)行3>
else:
<執(zhí)行4>
# 循環(huán)
for x in list:
do_something()
while <真值表達(dá)式>:
do_something()
異常處理
# python 內(nèi)置異常層級
# https://docs.python.org/3/library/exceptions.html#exception-hierarchy
try:
<語句>
except XError as e:
<發(fā)生X異常發(fā)生執(zhí)行的與語句>
except YError as e:
<發(fā)生Y異常發(fā)生執(zhí)行的與語句>
else:
<沒有發(fā)生異常會(huì)執(zhí)行的語句>
finally:
<無論如何都會(huì)執(zhí)行的語句>
函數(shù)
from __future__ import print_function
from functools import partial
# 函數(shù)定義
# 位置參數(shù),必選參數(shù)
def einstein_say(msg):
print("Einstein said:", msg)
def newton_say(msg):
print("Newton said:", msg)
# 默認(rèn)參數(shù),關(guān)鍵字參數(shù)
def someone_say(who="I", msg="Life is short, you need Python"):
print(who, "said:", msg)
someone_say()
someone_say("Einstein", "E=MC^2")
someone_say("Newton", "Where is my Apple?")
someone_say(msg="slot_1 is mst", who="slot_2 is who")
someone_say(msg="nothing")
kw = {"who":"I", "msg": "kw args"}
someone_say(**kw)
# 不定參數(shù) tuple
def sanzang_say(*msgs):
for msg in msgs:
print("TangSanZang said:", msg)
quotations = (u"阿彌陀佛", u"貧僧是從東土大唐而來去往西天拜佛求經(jīng)的。", u"施主!", u"善哉!善哉!", u"悟空,為師錯(cuò)怪你了 。")
sanzang_say(*quotations)
# 匿名函數(shù)
inc = (lambda x: x + 1)
print(inc(1))
print(inc(2))
# 列表生成式
g = (x**3 for x in [1, 2, 3, 4, 5] if x > 1)
g.next()
for ele in g:
print(ele)
print("%s- - - - - - - -%s" % ("|<", ">|"))
# 列表表達(dá)式
x = [x**3 for x in [1, 2, 3] if x > 1]
for ele in x:
print(ele)
# 裝飾器 閉包 高階函數(shù)
def aspect_log(**anno_args):
def aspect_log_func(func):
def func_wrapper(*args, **kwargs):
print("start",anno_args["name"], "->", anno_args["order"])
func(*args, **kwargs)
print("end", anno_args["name"], "->", anno_args["order"])
return func_wrapper
return aspect_log_func
@aspect_log(name = "default", order = 2)
def simple_func():
print("simple func do nothing")
simple_func()
# 偏函數(shù)
bin2Dec = partial(int, base=2)
hex2Dec = partial(int, base=16)
print(bin2Dec('1000'))
print(hex2Dec('400'))
類
import inspect
class Human(object):
"""
示例類注釋: 人類定義
"""
def __init__(self, name):
"""示例方法注釋: 初始構(gòu)造函數(shù)"""
super(Human, self).__init__()
self._name = name
self.__age = 18 # __開始的屬性表示私有屬性 外部不可訪問 已變成_ClassName__age
@staticmethod # 靜態(tài)方法
def thinking():
pass
@classmethod # 類方法
def speak(cls):
pass
@property # 屬性
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
class Chinese(Human):
pass
class HeNanPeople(Chinese):
pass
class American(Human):
pass
'''
O python2.2之前 經(jīng)典類DFS
/ \ python2.2 新式類BFS
/ \ python2.3后 C3算法
A B
/ \ / \
/ \ / \
C D E
\ | /
\ | /
F
方法解析順序(Method Resolution Order,MRO)定義了多繼承存在時(shí) Python 解釋器查找函數(shù)解析的正確方式。
MRO 核心解決兩個(gè)問題,【本地優(yōu)先級】 和 【單調(diào)性】
DFS,BFS算法均無法解決單調(diào)性問題
C3 算法:
The name C3 refers to the three important properties of the resulting linearization: a consistent extended precedence graph, preservation of local precedence order, and fitting the monotonicity criterion. (The name "C3" is not an initialism.)
算法描述:
1. 如果第一個(gè)序列的第一個(gè)元素,是后續(xù)其他序列的第一個(gè)元素,或者不再后續(xù)序列中再次出現(xiàn),則將這個(gè)元素合并到最終的方法解析順序序列中,并從當(dāng)前操作的全部序列中刪除。
2. 如果不符合,則跳過此元素,查找下一個(gè)列表的第一個(gè)元素,重復(fù)1的判斷規(guī)則
L(C) = [C] + merge(L(A),[A]) = [C,A,O]
L(D) = [D] + merge(L(A),L(B),[A,B])
= [D] + merge([A,O], [B,O], [A,B])
= [D,A,B,O]
L(E) = [E] + merge(L(B),[B]) = [E,B,O]
L(F) = [F] + merge(L(C), L(D), L(E), [C,D,E])
= [F] + merge([C,A,O],[D,A,B,O],[E,B,O],[C, D,E])
= [F, C] + merge([A,O], [D,A,B,O], [E,B,O],[D,E])
= [F, C, D] + merge([A,O], [A,B,O], [E,B,O], [E])
= [F, C, D, A] + merge([O], [B,O], [E,B,O],[E])
= [F, C, D, A, E] + merge([O], [B,O], [B,O])
= [F, C, D, A, E, B, O]
'''
class T(object):
pass
class A(T):
pass
class B(T):
pass
class C(A, B):
pass
ot = T()
oa = A()
print(type(ot), ot.__class__)
print(type(oa), oa.__class__)
print(inspect.getmro(C)) # 獲取C的方法解析序列
-
參考文檔
[1] Python2.X官方文檔
[2] C3算法詳解
[3] 廖雪峰Python教程