數(shù)據(jù)類型(也是對象來的)
整數(shù)(0xffe3)薇正、浮點數(shù)(1.23e5==1.23*10的5次方)洛心、字符串、True和False(使用and葬毫、or镇辉、not運算)、None(不等于0)
注意:沒有常量(python把全大寫變量定義為常量)
數(shù)據(jù)結(jié)構(gòu)
- tuple
(v1,v2,v3)或者v1,v2,v3
- list
[v1,v2,v3]贴捡,list[index]忽肛,len(list) == 3,元素多了就慢但內(nèi)存少
- dict
{k1:v1,k2:v2}烂斋,dict[k1] == v1屹逛,if k1 in dict,k1和k2可以不同類型汛骂,快但內(nèi)存多
- set
set([k1,k2,k3])罕模,元素是dict的key,所以不重復(fù)且不可變對象
注意:運算符&交集帘瞭,|并集
高級特性
- 切片
list[-2:]
- 迭代key:
for key in dict
- 迭代字符串:
for 變量 in 'ABC'
- 列表生成式:
[x * x for x in range(1, 11) if x % 2 == 0]淑掌,[m + n for m in 'ABC' for n in 'XYZ']
- generator
next(),(x * x for x in range(10))蝶念,不占用空間抛腕,函數(shù)中yield v1到y(tǒng)ield vn,可for媒殉,send(value)就是給(yield v)賦值担敌,但啟動generator時只能使用send(None),此時相當(dāng)與next()廷蓉。
注意:可for為Iterable全封,可next為Iterator,iter(Iterable) == Iterator
函數(shù)
-
高階函數(shù)
# 高階函數(shù):以函數(shù)作為參數(shù) def add(x, y, f): return f(x) + f(y) # map() def f(x): return x * x r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) # list(list(r)) == [1, 4, 9, 16, 25, 36, 49, 64, 81] # type(r) == map,未解?map函數(shù)居然是一個class #reduce() def add(x, y): return x + y reduce(add, [1, 3, 5, 7, 9]) # 結(jié)果:25 #filter 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] #sorted sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True) # 結(jié)果:['Zoo', 'Credit', 'bob', 'about'] # 加條件:key=func # 反向排序:reverse=True
-
閉包
引用作用域以外的變量
-
裝飾器
def deco(function): # 由外到內(nèi)調(diào)用 print("輸出結(jié)果:") # 外 def _deco(string): print("before") # 內(nèi) function(string) print("before") return _deco @deco def p(arg): print(arg) p("hello") # 相當(dāng)于deco(p)("hello")刹悴,而不是deco(p("hello")) # 輸出結(jié)果: # before # hello # before
注:函數(shù)作為參數(shù)時不要帶參數(shù)给猾,帶參數(shù)表示調(diào)用
-
偏函數(shù)
帶有默認(rèn)參數(shù)(key-value)的函數(shù)
int('110', base=2) # 二進(jìn)制數(shù)“10”轉(zhuǎn)十進(jìn)制輸出 #結(jié)果:6 def int2(x, base=2): return int(x, base) #相當(dāng)于:int2 = functools.partial(int, base=2)
面向?qū)ο?/h4>
只有對象里頭的才叫method,其余的都叫function
-
私有方法
_xxx or __xxx颂跨,區(qū)別_xxx仍可訪問,__xxx解釋成_ClassName__xxx
注:obj.__xxx可賦值扯饶,但get_xxx()針對的是_ClassName__xxx恒削,而不是__xxx
-
類屬性與實例屬性
- 類屬性直接定義,不通過self.xxx定義
- 訪問實例屬性時尾序,先找實例屬性钓丰,沒有時再找類屬性
-
給類或?qū)ο蠼壎ǚ椒?/p>
帶有self的外部方法set_name(self,name)
- 實例方法:obj.set_name = MethodType(set_name, Obj),僅對單個實例有效
- 類方法:ClassName.set_name = set_name
注:obj.method = MethodType(method,Obj)與Obj.method = MethodType(method,Obj)不同每币,Obj.method相當(dāng)于java靜態(tài)
type還可以動態(tài)創(chuàng)建類:
def func(self, name):
print(name)
# type([class_name],[父類tuple],[鍵值對:{[類的函數(shù)名]:[已定義好的函數(shù)名]}])
h = type('Hello', (object,), {"hello": func})
h().hello("Mike")
# 輸出結(jié)果:Mike
- __slots__
class xxx(object):
__slots__ = ("name","age") # 那么該類只允許name和age屬性
# 注:其子類不受限制
- @property
class Student(object):
# 設(shè)置可讀屬性
@property # @property相當(dāng)于一個getter携丁,并生成birth裝飾器
def birth(self):
return self._birth
# 設(shè)置可寫屬性
@birth.setter
def birth(self, value):
self._birth = value
@property
def age(self):
return 2017 - self._birth
stu = Student()
stu.birth = 1993
print(stu.age)
# 結(jié)果:24
- Python支持多繼承class class_name(Obj1,Obj2)(這點和Java單繼承不同)
- __iter__(注:通常與next()、StopInteration()配套使用)
# __iter__()方法返回一個迭代對象兰怠,
# 然后梦鉴,Python的for循環(huán)就會不斷調(diào)用該迭代對象的__next__()方法,
# 拿到循環(huán)的下一個值揭保,直到遇到StopIteration錯誤時退出循環(huán)
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1
def __iter__(self):
return self # 實例本身就是迭代對象肥橙,故返回自己
def __next__(self):
self.a, self.b = self.b, self.a + self.b # 計算下一個值
if self.a > 100000: # 退出循環(huán)的條件
raise StopIteration()
return self.a # 返回下一個值
for num in Fib():
print(num)
# 結(jié)果輸出:1 1 2 3 5 ... 46368 75025
- 枚舉類
# @unique裝飾器可以幫助我們檢查保證沒有重復(fù)值
@unique
class Weekday(Enum):
Sun = 0 # Sun的value被設(shè)定為0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
Exception
- 如何知道程序出問題?
使用raise Err來拋出異常
(注:所有Err都是BaseException的子類秸侣,raise也可不加Err)
- 拋出錯誤后如何處理存筏?
通過try:...except:...finally:...
多進(jìn)程與多線程
- 多進(jìn)程
方式一:使用os.fork(),注:windows無法調(diào)用fork()
print('Process-%s start...' % os.getpid())
pid = os.fork() # 之后的代碼分別在當(dāng)前進(jìn)程和子進(jìn)程中執(zhí)行
if pid == 0: # 返回0是子進(jìn)程味榛,父進(jìn)程返回子進(jìn)程id
print('I am child process (%s) and my parent is %s.'
% (os.getpid(), os.getppid()))
else:
print('I (%s) just created a child process (%s)' % (os.getpid(), pid))
只有對象里頭的才叫method,其余的都叫function
私有方法
_xxx or __xxx颂跨,區(qū)別_xxx仍可訪問,__xxx解釋成_ClassName__xxx
注:obj.__xxx可賦值扯饶,但get_xxx()針對的是_ClassName__xxx恒削,而不是__xxx
類屬性與實例屬性
- 類屬性直接定義,不通過self.xxx定義
- 訪問實例屬性時尾序,先找實例屬性钓丰,沒有時再找類屬性
給類或?qū)ο蠼壎ǚ椒?/p>
帶有self的外部方法set_name(self,name)
- 實例方法:obj.set_name = MethodType(set_name, Obj),僅對單個實例有效
- 類方法:ClassName.set_name = set_name
注:obj.method = MethodType(method,Obj)與Obj.method = MethodType(method,Obj)不同每币,Obj.method相當(dāng)于java靜態(tài)
type還可以動態(tài)創(chuàng)建類:
def func(self, name):
print(name)
# type([class_name],[父類tuple],[鍵值對:{[類的函數(shù)名]:[已定義好的函數(shù)名]}])
h = type('Hello', (object,), {"hello": func})
h().hello("Mike")
# 輸出結(jié)果:Mike
class xxx(object):
__slots__ = ("name","age") # 那么該類只允許name和age屬性
# 注:其子類不受限制
class Student(object):
# 設(shè)置可讀屬性
@property # @property相當(dāng)于一個getter携丁,并生成birth裝飾器
def birth(self):
return self._birth
# 設(shè)置可寫屬性
@birth.setter
def birth(self, value):
self._birth = value
@property
def age(self):
return 2017 - self._birth
stu = Student()
stu.birth = 1993
print(stu.age)
# 結(jié)果:24
# __iter__()方法返回一個迭代對象兰怠,
# 然后梦鉴,Python的for循環(huán)就會不斷調(diào)用該迭代對象的__next__()方法,
# 拿到循環(huán)的下一個值揭保,直到遇到StopIteration錯誤時退出循環(huán)
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1
def __iter__(self):
return self # 實例本身就是迭代對象肥橙,故返回自己
def __next__(self):
self.a, self.b = self.b, self.a + self.b # 計算下一個值
if self.a > 100000: # 退出循環(huán)的條件
raise StopIteration()
return self.a # 返回下一個值
for num in Fib():
print(num)
# 結(jié)果輸出:1 1 2 3 5 ... 46368 75025
# @unique裝飾器可以幫助我們檢查保證沒有重復(fù)值
@unique
class Weekday(Enum):
Sun = 0 # Sun的value被設(shè)定為0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
使用raise Err來拋出異常
(注:所有Err都是BaseException的子類秸侣,raise也可不加Err)
通過try:...except:...finally:...
方式一:使用os.fork(),注:windows無法調(diào)用fork()
print('Process-%s start...' % os.getpid())
pid = os.fork() # 之后的代碼分別在當(dāng)前進(jìn)程和子進(jìn)程中執(zhí)行
if pid == 0: # 返回0是子進(jìn)程味榛,父進(jìn)程返回子進(jìn)程id
print('I am child process (%s) and my parent is %s.'
% (os.getpid(), os.getppid()))
else:
print('I (%s) just created a child process (%s)' % (os.getpid(), pid))
方式二:使用Process(target=[function],args=[tuple_args])
def run_in_child_process(name):
if isinstance(name, (str,)):
print("child process %s is running!" % name)
else:
raise TypeError("Name should be str type!")
child_process_name = 'thread_demo'
p = Process(target=run_in_child_process, args= (child_process_name,), name=child_process_name)
print('process %s will start!' % p.name)
p.start()
p.join()
print('process %s is end!' % p.name)
方式三:啟動大量子進(jìn)程使用pool.apply_async([function],args=[tuple_args])
def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start)))
if __name__ == '__main__':
print('Parent process %s.' % os.getpid())
p = Pool(4) # 這里設(shè)置同時執(zhí)行的進(jìn)程數(shù)量為4椭坚,默認(rèn)為cpu核數(shù)
for i in range(5):
p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join() # 調(diào)用join之前必須close
print('All subprocesses done.')
- 多進(jìn)程與多線程的區(qū)別:
多進(jìn)程中,同一個變量搏色,各自有一份拷貝存在于每個進(jìn)程中善茎,互不影響,而多線程中继榆,所有變量都由所有線程共享 - 線程鎖Lock
balance = 0
def change_it(n):
# 先存后取巾表,結(jié)果應(yīng)該為0:
global balance
balance = balance + n
balance = balance - n
lock = threading.Lock()
def run_thread(n):
for i in range(100000):
# 先要獲取鎖:
lock.acquire()
try:
# 放心地改吧:
change_it(n)
finally:
# 改完了一定要釋放鎖:
lock.release()
補充
-
順序賦值
a, b = v1, v2 (or a, b = Iterable)
注:Iterable的長度和變量個數(shù)一致 -
匿名函數(shù):lambda
lambda x,y:(x+1)*y 相當(dāng)于 def func(x,y): return (x+1)*y
-
*args is a tuple, **kwargs is a dict
- 注:tuple變量作為參數(shù)傳入時也需要加星號,否則會被當(dāng)作一個Integer傳入
dir(obj):列出對象信息
Object略吨、int等等都是type類型
-
全局變量
- 函數(shù)中引用外部變量完全沒問題集币;
- 局部變量與全局變量同名是可以的,局部變量的修改不影響全局變量翠忠;
- 函數(shù)中可以使用global聲明來定義全局變量鞠苟。
-
字節(jié)與字符串互轉(zhuǎn)
bytes object
b = b"example"
str object
s = "example"
str to bytes
bytes(s, encoding = "utf8")
bytes to str
str(b, encoding = "utf-8")
an alternative method
str to bytes
str.encode(s)
bytes to str
bytes.decode(b)
另外,拼接字符串可以使用str.join(str_list)