常用語法點
1. functools.partial:
作用:創建偏函數
用法:簡單使用
int()函數還提供額外的base參數,默認值為10。如果傳入base參數,就可以做N進制的轉換
案例:修改系統的int函數,變成只轉換二進制數據
# 原型
>>>> import functools
>>>> int2 = functools.partial(int, base=2)
# 等價于
>>>> def int2(x, base=2):
return int(x, base)
2. 匿名函數lambda:
作用: 用來申明匿名函數
用法,簡單使用
關鍵字lambda表示匿名函數,冒號前面的x表示函數參數。
案例:使用關鍵字實現匿名函數:
# 原型
>>>> lambda x: x * x
# 等價于
>>>> def f(x) :
return x * x
3. 值得注意的代碼(一):
>>>> if __name__=='__main__':
test()
解釋:
當我們在命令行運行hello模塊文件時,Python解釋器把一個特殊變量"__name__"
置為"__main__",而如果在其他地方導入該hello模塊時,if判斷將失敗,因此,這種if
測試可以讓一個模塊通過命令行運行時執行一些額外的代碼,最常見的就是運行測試。
簡單用法:
4. 模塊搜索路徑:
目前:
當我們試圖加載一個模塊時,Python會在指定的路徑下搜索對應的.py文件,如果找不到,就會報錯
默認情況下,Python解釋器會搜索當前目錄、所有已安裝的內置模塊和第三方模塊,搜索路徑存放在sys
模塊的path變量中:
命令行查看
>>>> import sys
>>>> sys.path
自定義搜索路徑:
方法一:是直接修改sys.path,添加要搜索的目錄
>>> import sys
>>> sys.path.append('/Users/michael/my_py_scripts')
注意:這種方法是在運行時修改,運行結束后失效。
方法二:設置環境變量PYTHONPATH,該環境變量的內容會被自動添加到模塊搜索路徑中。設置方式與設置Path環境變量類似。注意只需要添加你自己的搜索路徑,Python自己本身的搜索路徑不受影響。
5. 給類與實例綁定方法
類(Student):
>>>> class Student(object):
gender = 'male'
實例(Tom & Jack):
>>>> Tom = Student()
>>>> Jack = Student()
方法一:
>>>> def set_score(self, score):
self.score = score
方法二:
>>>> def set_age(self, age):
self.age = age
-
給類綁定方法
>>>> Student.set_score = set_score
Tom.set_score(100)
Tom.score ~> 100Jack.set_score(90) Jack.score ~> 90
-
給實例綁定方法
from types import MethodType
>>>> Tom.set_age = MethodType(set_age, Tom)
Tom.set_age(20)
Tom.age ~> 20Jack.set_age(20) : ~> Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'set_age'
6. __slots__關鍵字
Python允許在定義class的時候,定義一個特殊的__slots__變量,來限制該class實例能添加的屬性:
參考代碼:
>>>> class Student(object):
slots = ('name', 'age') # 用tuple定義允許綁定的屬性名稱
效果:
>>>> s = Student() # 創建新的實例
>>>> 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'
解釋:
由于'score'沒有被放到__slots__中,所以不能綁定score屬性,試圖綁定score將得到AttributeError的錯誤。
注意:__slots__定義的屬性僅對當前類實例起作用,對繼承的子類是不起作用的。除非在子類中也定義__slots__,這樣,子類實例允許定義的屬性就是自身的__slots__加上父類的__slots__。
7. __getattr__方法
當調用不存在的屬性時,比如score,Python解釋器會試圖調用__getattr__(self, 'score')來嘗試獲得屬性,這樣,我們就有機會返回score的值。
注意:__getattr__方法不僅可以動態生成屬性,還能生成方法
__getattr__生成屬性
定義:
>>>> class Student(object):
def init(self):
self.name = 'Michael'
def getattr(self, attr):
if attr=='score':
return 99
使用:
>>> s = Student()
>>> s.name : ~>'Michael'
>>> s.score : ~> 99__getattr__生成方法
定義:
>>>> class Student(object):
def init(self):
self.name = 'Michael'
def getattr(self, attr):
if attr=='age':
return lambda:25
raise AttributedError(''Student' object has no attribute '%s'' % attr)
使用:
>>> s = Student()
>>> s.age() : ~> 25
8. __call__方法
一個對象實例可以有自己的屬性和方法,當我們調用實例方法時,我們用instance.method()來調用。能不能直接在實例本身上調用呢?在Python中,答案是肯定的。任何類,只需要定義一個__call__()方法,就可以直接對實例進行調用。
請看示例:
>>>> class Student(object):
def init(self, name):
self.name = name
def call(self):
print('My name is %s.' % self.name)
調用方式如下:
>>>> s = Student('Michael')
>>>> s() # self參數不要傳入My name is Michael.
總結:
- __call__()還可以定義參數。對實例進行直接調用就好比對一個函數進行調用一樣,所以你完全可以把對象看成函數,把函數看成對象,因為這兩者之間本來就沒啥根本的區別。
- 怎么判斷一個變量是對象還是函數呢?其實,更多的時候,我們需要判斷一個對象是否能被調用,能被調用的對象就是一個Callable對象,比如函數和我們上面定義的帶有__call__()的類實例:
>>>> callable(Student()) # True
>>>> callable([1, 2, 3]) # False - 通過callable()函數,我們就可以判斷一個對象是否是“可調用”對象。
9. type()函數
type()函數既可以返回一個對象類型,也可以創建出新的類型。
- 使用type()函數創建一個class對象
至少需要一次傳入3個參數:
a> class的名稱;
b> 繼承的父類集合,注意Python支持多重繼承,如果只有一個父類,別忘了tuple的單元素寫法;
c> class的方法名稱與函數綁定,這里我們把函數fn綁定到方法名hello上。
代碼實現:
>>>> Hello = type('Hello', (object,), dict(hello=fn)) # 創建Hello class
>>>> h = Hello()
>>>> h.hello() # Hello, world.
通過type()函數創建的類和直接寫class是完全一樣的,因為Python解釋器遇到class定義時,僅僅是掃描一下class定義的語法,然后調用type()函數創建出class。