python学习笔记——类与对象、常用函数
文章目錄
- 一、python的類與對象
- 1.1 基本概念
- 1.2 主要知識點
- 1.2.1 類屬性和實例屬性區別
- 1.2.2 self 是什么?
- 1.2.3 Python 的魔法方法__init__
- 1.2.4 繼承和覆蓋(super().\__init\__())
- 1.2.5公有和私有
- 1.3魔法方法
- 1.3.1 __init\__(self[, ...])
- 1.3.2 __new\__(cls[, ...])
- 1.3.3 __del\__(self)
- 1.3.4 算術運算符、反算術運算符、增量賦值運算符、一元運算符
- 1.3.5 屬性訪問
- 1.3.6 定制序列__len__()和__getitem__()
- 1.3.7 迭代器__iter\__() 與 __next\__()
- 1.4 擴展知識點
- 1.4.1 組合
- 1.4.2類的專有方法和內置函數
- 二、 基礎函數
- 2.1 Python5個內建高階函數(map、reduce、filter、sorted/sort、zip)
- 2.2 正則表達式
- 三、pycharm
- 3.1 常見報錯
一、python的類與對象
參考《datawhale——PythonLanguage》、《Python3 面向對象》
1.1 基本概念
對象 = 屬性 + 方法
對象是類的實例。換句話說,類主要定義對象的結構,然后我們以類為模板創建對象。類不但包含方法定義,而且還包含所有實例共享的數據
- 類(Class): 用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。
- 對象:通過類定義的數據結構實例。對象包括兩個數據成員(類變量和實例變量)和方法。
- 方法:類中定義的函數。
- 類屬性:類里面方法外面定義的變量稱為類屬性。類屬性所屬于類對象并且多個實例對象之間共享同一個類屬性,說白了就是類屬性所有的通過該類實例化的對象都能共享。
-
局部變量:定義在方法中的變量,只作用于當前實例的類。
-
實例屬性/變量:在類的聲明中,屬性是用變量來表示的。 實例屬性和具體的某個實例對象有關系,只能在自己的對象里面使用,其他的對象不能直接使用,不同實例對象的實例屬性不共享。實例變量用 self 修飾,因為self是誰調用,它的值就屬于該對象。
- 數據成員:類變量或者實例變量用于處理類及其實例對象的相關的數據。
- 方法重寫:改寫從父類繼承的方法,滿足子類的需求
- 繼承:派生類(derived class)繼承基類(base class)的字段和方法。所以子類自動共享父類之間數據和方法
- 多態:不同對象對同一方法響應不同的行動
- 實例化:創建一個類的實例,類的具體對象。
1.2 主要知識點
1.2.1 類屬性和實例屬性區別
- 類屬性:類外面,可以通過實例對象.類屬性和類名.類屬性進行調用。類里面,通過self.類屬性和類名.類屬性進行調用。
- 實例屬性 :類外面,可以通過實例對象.實例屬性調用。類里面,通過self.實例屬性調用。
- 實例屬性就相當于局部變量。出了這個類或者這個類的實例對象,就沒有作用了。
- 類屬性就相當于類里面的全局變量,可以和這個類的所有實例對象共享。
注意:屬性與方法名相同,屬性會覆蓋方法。
class A:def x(self):print('x_man')aa = A() aa.x() # x_man aa.x = 1 print(aa.x) # 1 aa.x() # TypeError: 'int' object is not callable1.2.2 self 是什么?
Python 的 self 相當于 C++ 的 this 指針。
在類的內部,使用 def 關鍵字來定義一個方法,與一般函數定義不同,類方法必須包含參數 self, 且為第一個參數,self 代表的是類的實例。(對應于該實例,即該對象本身)在調用方法時,我們無需明確提供與參數 self 相對應的參數
1.2.3 Python 的魔法方法__init__
類有一個名為__init__(self[, param1, param2…])的魔法方法,該方法在類實例化時會自動調用。
class Ball:def __init__(self, name):self.name = namedef kick(self):print("我叫%s,該死的,誰踢我..." % self.name)a = Ball("球A") b = Ball("球B") a.kick() # 我叫球A,該死的,誰踢我... b.kick() # 我叫球B,該死的,誰踢我...1.2.4 繼承和覆蓋(super()._init_())
派生類(derived class)繼承基類(base class)的字段和方法。如果子類中定義與父類同名的方法或屬性,則會自動覆蓋父類對應的方法或屬性。多繼承時基類方法名相同,子類沒有指定時,使用靠前的父類的方法。
# 類定義 class people:# 定義基本屬性name = ''age = 0# 定義私有屬性,私有屬性在類外部無法直接進行訪問__weight = 0# 定義構造方法def __init__(self, n, a, w):self.name = nself.age = aself.__weight = wdef speak(self):print("%s 說: 我 %d 歲。" % (self.name, self.age))# 單繼承示例 class student(people):grade = ''def __init__(self, n, a, w, g):# 調用父類的構函數people.__init__(self, n, a, w)#super().__init__()也可以,表示繼承父類的init操作self.grade = g# 覆寫父類的方法def speak(self):print("%s 說: 我 %d 歲了,我在讀 %d 年級" % (self.name, self.age, self.grade))s = student('小馬的程序人生', 10, 60, 3) s.speak() # 小馬的程序人生 說: 我 10 歲了,我在讀 3 年級注意:如果上面的程序去掉:people.init(self, n, a, w),則輸出: 說: 我 0 歲了,我在讀 3 年級,因為子類的構造方法把父類的構造方法覆蓋了。如果繼承的方法中含有父類init的屬性但是沒有在子類中實現,會報錯。此時可以
- 調用未綁定的父類方法base class.init(self,*kargs)
- 使用super函數super()._init_()
多繼承時需要注意圓括號中父類的順序,若是父類中有相同的方法名,而在子類使用時未指定,Python 從左至右搜索,調用靠前的類的此方法。
# 另一個類,多重繼承之前的準備 class Speaker:topic = ''name = ''def __init__(self, n, t):self.name = nself.topic = tdef speak(self):print("我叫 %s,我是一個演說家,我演講的主題是 %s" % (self.name, self.topic)) # 多重繼承 class Sample01(Speaker, Student):a = ''def __init__(self, n, a, w, g, t):Student.__init__(self, n, a, w, g)Speaker.__init__(self, n, t)# 方法名同,默認調用的是在括號中排前地父類的方法 test = Sample01("Tim", 25, 80, 4, "Python") test.speak() # 我叫 Tim,我是一個演說家,我演講的主題是 Python class Sample02(Student, Speaker):a = ''def __init__(self, n, a, w, g, t):Student.__init__(self, n, a, w, g)Speaker.__init__(self, n, t)# 方法名同,默認調用的是在括號中排前地父類的方法 test = Sample02("Tim", 25, 80, 4, "Python") test.speak() # Tim 說: 我 25 歲了,我在讀 4 年級1.2.5公有和私有
變量名或函數名前加上“__”兩個下劃線,那么這個函數或變量就會為私有的了。
- 私有屬性在類外部無法直接進行訪問。
- 私有方法只能在類的內部調用 ,不能在類的外部調用
【例子】類的私有屬性實例
【例子】類的私有方法實例
class Site:def __init__(self, name, url):self.name = name # publicself.__url = url # privatedef who(self):print('name : ', self.name)print('url : ', self.__url)def __foo(self): # 私有方法print('這是私有方法')def foo(self): # 公共方法print('這是公共方法')self.__foo()x = Site('老馬的程序人生', 'https://blog.csdn.net/LSGO_MYP') x.who() # name : 老馬的程序人生 # url : https://blog.csdn.net/LSGO_MYPx.foo() # 這是公共方法 # 這是私有方法 x.__foo()#報錯,外部不能使用私有方法 # AttributeError: 'Site' object has no attribute '__foo'1.3魔法方法
魔法方法總是被雙下劃線包圍,例如__init__。魔法方法的“魔力”體現在它們總能夠在適當的時候被自動調用。
魔法方法的第一個參數應為cls(類方法) 或者self(實例方法):
- cls:代表一個類的名稱
- self:代表一個實例對象的名稱
1.3.1 __init__(self[, …])
__init__(self[, …]) :構造器,當一個實例被創建的時候調用的初始化方法
1.3.2 __new__(cls[, …])
__new__方法主要是當你繼承一些不可變的 class 時(比如int, str, tuple), 提供給你一個自定義這些類的實例化過程的途徑。
在一個對象實例化的時候所調用的第一個方法,在調用__init__初始化前,先調用__new__。 __new__至少要有一個參數cls,代表要實例化的類,此參數在實例化時由 Python 解釋器自動提供,后面的參數直接傳遞給__init__。 __new__對當前類進行了實例化,并將實例返回,傳給__init__的self。 但是,執行了__new__,并不一定會進入__init__,只有__new__返回了當前類cls的實例,當前類的__init__才會進入。1.3.3 __del__(self)
- 析構器,當一個對象將要被系統回收之時調用的方法。
大部分時候,Python 的 ARC(自動引用計數,用來回收對象所占用的空間) 都能準確、高效地回收系統中的每個對象。但如果系統中出現循環引用的情況,比如對象 a 持有一個實例變量引用對象 b,而對象 b 又持有一個實例變量引用對象 a,此時兩個對象的引用計數都是 1,而實際上程序已經不再有變量引用它們,系統應該回收它們,此時 Python 的垃圾回收器就可能沒那么快,要等專門的循環垃圾回收器(Cyclic Garbage Collector)來檢測并回收這種引用循環。
1.3.4 算術運算符、反算術運算符、增量賦值運算符、一元運算符
例如以下運算符。詳見《PythonLanguage/14. 魔法方法.md》
常見± */和+= -=等等
1.3.5 屬性訪問
__getattr__(self, name): 定義當用戶試圖獲取一個不存在的屬性時的行為。 __getattribute__(self, name):定義當該類的屬性被訪問時的行為(先調用該方法,查看是否存在該屬性,若不存在,接著去調用__getattr__)。 __setattr__(self, name, value):定義當一個屬性被設置時的行為。 __delattr__(self, name):定義當一個屬性被刪除時的行為。1.3.6 定制序列__len__()和__getitem__()
容器類型的協議
- 如果說你希望定制的容器是不可變的話,你只需要定義__len__()和__getitem__()方法。
- 如果你希望定制的容器是可變的話,除了__len__()和__getitem__()方法,你還需要定義__setitem__()和__delitem__()兩個方法。
- __len__(self)定義當被len()調用時的行為(返回容器中元素的個數)。
- __getitem__(self, key)定義獲取容器中元素的行為,相當于self[key]。
- __setitem__(self, key, value)定義設置容器中指定元素的行為,相當于self[key] = value。
- __delitem__(self, key)定義刪除容器中指定元素的行為,相當于del self[key]。
【例子】編寫一個不可改變的自定義列表,要求記錄列表中每個元素被訪問的次數。
class CountList:def __init__(self, *args):self.values = [x for x in args]self.count = {}.fromkeys(range(len(self.values)), 0)def __len__(self):return len(self.values)def __getitem__(self, item):self.count[item] += 1return self.values[item]c1 = CountList(1, 3, 5, 7, 9) c2 = CountList(2, 4, 6, 8, 10) print(c1[1]) # 3 print(c2[2]) # 6 print(c1[1] + c2[1]) # 7print(c1.count) # {0: 0, 1: 2, 2: 0, 3: 0, 4: 0}print(c2.count) # {0: 0, 1: 1, 2: 1, 3: 0, 4: 0}【例子】編寫一個可改變的自定義列表,要求記錄列表中每個元素被訪問的次數。
class CountList:def __init__(self, *args):self.values = [x for x in args]self.count = {}.fromkeys(range(len(self.values)), 0)def __len__(self):return len(self.values)def __getitem__(self, item):self.count[item] += 1return self.values[item]def __setitem__(self, key, value):self.values[key] = valuedef __delitem__(self, key):del self.values[key]for i in range(0, len(self.values)):if i >= key:self.count[i] = self.count[i + 1]self.count.pop(len(self.values))c1 = CountList(1, 3, 5, 7, 9) c2 = CountList(2, 4, 6, 8, 10) print(c1[1]) # 3 print(c2[2]) # 6 c2[2] = 12 print(c1[1] + c2[2]) # 15 print(c1.count) # {0: 0, 1: 2, 2: 0, 3: 0, 4: 0} print(c2.count) # {0: 0, 1: 0, 2: 2, 3: 0, 4: 0} del c1[1] print(c1.count) # {0: 0, 1: 0, 2: 0, 3: 0}1.3.7 迭代器__iter_() 與 __next_()
- 迭代是 Python 最強大的功能之一,是訪問集合元素的一種方式。字符串,列表或元組對象都可用于創建迭代器。
- 迭代器是一個可以記住遍歷的位置的對象。迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會后退。
- 迭代器有兩個基本的方法:iter() 和 next()。
下面兩個例子返回的結果是一樣的
string = 'lsgogroup' for c in string:print(c) for c in iter(string):print(c) links = {'B': '百度', 'A': '阿里', 'T': '騰訊'} for each in links:print('%s -> %s' % (each, links[each]))for each in iter(links):print('%s -> %s' % (each, links[each]))- iter(object) 函數用來生成迭代器。
- next(iterator[, default]) 返回迭代器的下一個項目。iterator表示可迭代對象,default – 可選,用于設置在沒有下一個元素時返回該默認值,如果不設置,又沒有下一個元素則會觸發 StopIteration 異常。
把一個類作為一個迭代器使用需要在類中實現兩個魔法方法 __iter_() 與 __next_() 。
把一個類作為一個迭代器使用需要在類中實現兩個魔法方法 iter() 與 next() 。
__iter__(self)定義當迭代容器中的元素的行為,返回一個特殊的迭代器對象, 這個迭代器對象實現了 __next__() 方法并通過 StopIteration 異常標識迭代的完成。__next__() 返回下一個迭代器對象。StopIteration 異常用于標識迭代的完成,防止出現無限循環的情況,在 __next__() 方法中 我們可以設置在完成指定循環次數后觸發 StopIteration 異常來結束迭代。 class Fibs:def __init__(self, n=10):self.a = 0self.b = 1self.n = ndef __iter__(self):return selfdef __next__(self):self.a, self.b = self.b, self.a + self.bif self.a > self.n:raise StopIterationreturn self.afibs = Fibs(100) for each in fibs:print(each, end=' ')# 1 1 2 3 5 8 13 21 34 55 891.4 擴展知識點
1.4.1 組合
class Turtle:def __init__(self, x):self.num = xclass Fish:def __init__(self, x):self.num = xclass Pool:def __init__(self, x, y):self.turtle = Turtle(x)self.fish = Fish(y)def print_num(self):print("水池里面有烏龜%s只,小魚%s條" % (self.turtle.num, self.fish.num))p = Pool(2, 3) p.print_num() # 水池里面有烏龜2只,小魚3條1.4.2類的專有方法和內置函數
具體見《datawhale——PythonLanguage》
類的專有方法:
內置函數:
- issubclass(class, classinfo) 方法用于判斷參數 class 是否是類型參數 classinfo 的子類。一個類被認為是其自身的子類。
- isinstance(object, classinfo) 方法用于判斷一個對象是否是一個已知的類型,類似type()。
- hasattr(object, name)用于判斷對象是否包含對應的屬性。
- getattr(object, name[, default])用于返回一個對象屬性值。
- setattr(object, name, value)對應函數 getattr(),用于設置屬性值,該屬性不一定是存在的。
- delattr(object, name)用于刪除屬性。
- class property([fget[, fset[, fdel[, doc]]]])用于在新式類中返回屬性值
二、 基礎函數
2.1 Python5個內建高階函數(map、reduce、filter、sorted/sort、zip)
參考《PythonLanguage/Python高階函數使用總結.md》
2.2 正則表達式
參考《Python3 正則表達式》
三、pycharm
3.1 常見報錯
在cmd中輸入jupyter notebook啟動jupyter,然后將其網站復制到pycharm中。
2.系統新建項目使用的新的python環境,很多以前的包沒有安裝
設置python解釋器為原來的解釋器,如下圖所示,找到原python.exe文件位置就行:
總結
以上是生活随笔為你收集整理的python学习笔记——类与对象、常用函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 进程 ldt,LInux 描
- 下一篇: python椭圆拟合_椭圆拟合(pyth