python类和对象详解_Python公开课 - 详解面向对象
前言
在C語言中,單純通過結(jié)構(gòu)化的函數(shù)也可以實(shí)現(xiàn)很好的軟件,順序思路比較好理解;而C++則以面向?qū)ο蟮乃季S來進(jìn)行代碼組織,通過定義對(duì)象、成員變量、成員函數(shù)、以封裝、繼承和多態(tài)等方式來更靈活處理業(yè)務(wù)邏輯。
Python從設(shè)計(jì)之初就已經(jīng)是一門面向?qū)ο蟮恼Z言,正因?yàn)槿绱?#xff0c;在Python中創(chuàng)建一個(gè)類和對(duì)象是很容易的。本章節(jié)我們將詳細(xì)介紹Python的面向?qū)ο缶幊獭?/p>
理解對(duì)象和實(shí)例
對(duì)于初學(xué)者來說,這兩個(gè)詞太抽象,我們其實(shí)可以把他具象化來看。現(xiàn)實(shí)生活中,經(jīng)常會(huì)有一些流程規(guī)章辦法,我們要按照這些規(guī)章辦法來做事。
例如要考情流程,那么對(duì)于考情流程的定義,你可以把它理解就是一個(gè)類,而對(duì)于你每天實(shí)際考勤打卡的情況,就是這個(gè)類的實(shí)例了。
抽象點(diǎn)理解:類是定義,實(shí)例則是依賴于這個(gè)定義產(chǎn)生的具體行為集合。
面向?qū)ο蟮幕靖拍?/p>
類: 用來描述具有相同的屬性和方法的對(duì)象的集合。它定義了該集合中每個(gè)對(duì)象所共有的屬性和方法。
類變量:類變量在整個(gè)實(shí)例化的對(duì)象中是公用的。類變量定義在類中且在函數(shù)體之外。類變量通常不作為實(shí)例變量使用。
成員變量:類變量或者實(shí)例變量用于處理類及其實(shí)例對(duì)象的相關(guān)的數(shù)據(jù)。
成員函數(shù):類中定義的函數(shù)。
方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對(duì)其進(jìn)行改寫,這個(gè)過程叫方法的覆蓋(override),也稱為方法的重寫。
局部變量:定義在方法中的變量,只作用于當(dāng)前實(shí)例的類。
實(shí)例變量:在類的聲明中,屬性是用變量來表示的。這種變量就稱為實(shí)例變量,是在類聲明的內(nèi)部但是在類的其他成員方法之外聲明的。
繼承:即一個(gè)派生類(derived class)繼承基類(base class)的字段和方法。繼承也允許把一個(gè)派生類的對(duì)象作為一個(gè)基類對(duì)象對(duì)待。
實(shí)例化:創(chuàng)建一個(gè)類的實(shí)例的過程,也就是創(chuàng)建一個(gè)類的具體對(duì)象。
對(duì)象:通過類定義的數(shù)據(jù)結(jié)構(gòu)實(shí)例。
例如:
class Animal(object):
version = '1.0'
def __init__(self, name):
self.name = name
def getName(self):
return self.name
class Cat(Animal):
def __init__(self, name):
Animal.__init__(self, name)
self.nick_name = 'Tom'
def getNickName(self):
return self.nick_name
def getName(self):
prefix = "override"
return "[%s:]%s" %(prefix, self.name)
a = Cat('cat')
print(a.getName(), a.nick_name, a.getNickName())
輸出:
[override:]cat Tom Tom
示例說明:
class: 類定義關(guān)鍵字,即聲明以下代碼塊是一個(gè)類
version: 類變量
name, nick_name: 成員變量
getName, getNickName: 成員函數(shù)
prefix: 成員函數(shù)中的局部變量
a.nick_name: 實(shí)例變量
class Cat(Animal)::繼承,即Cat繼承于Animal
a = Cat('cat'): 實(shí)例化一個(gè)cat對(duì)象
a: 一個(gè)cat對(duì)象
封裝
我們定義一個(gè)類,需要將他的基本屬性進(jìn)行封裝,例如定義一個(gè)學(xué)生類,他包含了名字和年齡兩個(gè)屬性及對(duì)應(yīng)的get/set方法:
class Student:
def __init__(self):
self.name = ""
self.__age = 0 #定義私有屬性,私有屬性在類外部無法直接進(jìn)行訪問
def setName(self, name):
self.name = name
def setAge(self, age):
self.__age = age
def getName(self):
return self.name
def getAge(self):
return self.__age
o = Student()
o.setName("Alex")
o.setAge(18)
print(o.getName(), o.getAge())
print(o.name)
print(o.__age)
輸出:
Alex 18
Alex
Traceback (most recent call last):
File "test13.py", line 25, in
print(o.__age)
AttributeError: 'Student' object has no attribute '__age'
示例說明:
__init__: 構(gòu)造函數(shù),該方法在類實(shí)例化時(shí)會(huì)自動(dòng)調(diào)用
self: 相當(dāng)于C++中的this關(guān)鍵字,代表是類的實(shí)例
__age: 聲明該屬性為私有,不能在類的外部被使用或直接訪問, 同理成員函數(shù)如果加上__也是一樣
繼承與多重繼承
在上面的例子中已經(jīng)說明了Python如何進(jìn)行繼承,下面我們闡述一下如何進(jìn)行多重繼承
class A:
def say(self):
print('say hi')
class B:
def listen(self):
print('listen story')
class C:
def eat(self):
print('eat food')
class Multi(A, B, C):
def test(self):
pass
obj = Multi()
obj.say()
obj.listen()
obj.eat()
輸出:
say hi
listen story
eat food
注意:
需要注意圓括號(hào)中父類的順序,若是父類中有相同的方法名,而在子類使用時(shí)未指定,python從左至右搜索 即方法在子類中未找到時(shí),從左到右查找父類中是否包含方法
多態(tài)
重載與重寫
重載是指同一個(gè)類中的多個(gè)方法具有相同的名字,但這些方法具有不同的參數(shù)列表,即參數(shù)的數(shù)量或參數(shù)類型不能完全相同
重寫是存在子父類之間的,子類定義的方法與父類中的方法具有相同的方法名字,相同的參數(shù)表和相同的返回類型
class A:
def test1(self, a, b):
self.a = a
self.b = b
print('A.test1')
def test2(self, c):
self.c = c
print('A.test2')
class S(A):
def test1(self, a, b, c):
self.a = a
self.b = b
self.c = c
print('S.test1')
def test2(self, c):
print('S.test2')
a = A()
s = S()
a.test1(1, 2)
a.test2(1)
s.test1(1, 2, 3)
s.test2(1)
s.test1(1, 2)
輸出:
A.test1
A.test2
S.test1
S.test2
Traceback (most recent call last):
File "test15.py", line 30, in
s.test1(1, 2)
TypeError: test1() missing 1 required positional argument: 'c'
注意:
上面例子可以看出,雖然我們?cè)谧宇怱中重載了父類A的方法test1,但是執(zhí)行報(bào)錯(cuò)了,原因在于Python3中是不支持函數(shù)重載,因?yàn)?Python 可以接受任何類型的參數(shù),如果函數(shù)的功能相同,那么不同的參數(shù)類型在 Python 中很可能是相同的代碼,沒有必要做成兩個(gè)不同函數(shù)。
也就是說,我們只需要將子類S稍作改動(dòng)即可:
class S(A):
def test1(self, *attr):
self.attr = list(attr)
print('S.test1 %s' %self.attr)
def test2(self, c):
print('S.test2')
輸出:
A.test1
A.test2
S.test1 [1, 2, 3]
S.test2
S.test1 [1, 2]
獲取類的屬性
使用type()
判斷對(duì)象類型,使用type()函數(shù)
>>> type(S)
使用isinstance()
判斷class的類型,可以使用isinstance()函數(shù)
>>>isinstance(s, S)
True
>>>isinstance(s, A)
True
使用dir()
獲得一個(gè)對(duì)象的所有屬性和方法,可以使用dir()函數(shù),它返回一個(gè)包含字符串的list
>>>dir(s)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'attr', 'test1', 'test2']
相關(guān)閱讀
總結(jié)
以上是生活随笔為你收集整理的python类和对象详解_Python公开课 - 详解面向对象的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: arg是什么函数_C 语言编程 — 函数
- 下一篇: python调用exe程序 传入参数_关