1. 程式人生 > 其它 >python類與物件

python類與物件

python類與物件

python通過類來建立物件,物件是類的例項。

1.類的定義

類通過class + 類名的方式定義

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

類名的首字母一般用大寫,類中的函式稱為方法。

2.Class物件

類的物件支援兩種操作:屬性引用和例項化

(1)屬性引用

如上述程式碼通過Myclass.i或Myclass.f即可返回一個整數和一個函式,並且可以通過複製Myclass.i來改變他的值。

print(MyClass.i)
MyClass.i = 10
print(MyClass.i)
print(type(MyClass.f)
#12345
#10
#<class 'function'>)
(2)例項化
x = Myclass()

這裡的x便是類的例項。

3.__init__方法

這是一個特殊的方法,當例項化類時會自動呼叫該方法。

許多類喜歡建立帶有特定初始狀態的自定義例項。 為此類定義可能包含這個方法,就像這樣:

class Jump:
    def __init__(self,name):
        self.name = name
    def jump(self):
        print(f'{self.name} is jumping now!')
a = Jump("小a")
a.jump()
#小a is jumping now!

當建立一個例項時這個方法自動使self.name賦值為"小a"。

如果沒有這個方法,那上面的例子就應當這麼寫:

class Jump:
    def name(self,name):
        self.name=name
    def jump(self):
        print(f'{self.name} is jumping now!')
a = Jump()
a.name("小a")
a.jump()
#小a is jumping now!

我們還要再呼叫一次name的方法。

4.例項物件

例項物件能理解的唯一操作是屬性引用,有兩種有效的屬性名稱:資料引用和方法

(1)資料引用

例項可以引用類中的資料

class MyClass:
    i = 12345
    def f(self):
        return 'hello world'
a = MyClass()
print(a.i)
#12345

但是運用例項改變所引用的資料時,類原本的資料不會改變

a.i = 10
print(MyClass.i)
#12345
(2)方法

例項可以引用類中的方法

通常方法物件在繫結後直接被呼叫,但是也直接呼叫也不是必須的,我們可以將其保留起來。

class MyClass:
    i = 12345
    def f(self):
        return 'hello world'
xf = x.f
while True:
    print(xf())

將會一直輸出,直到結束。

我們會發現這裡上面呼叫 x.f() 時並沒有帶引數,雖然 f() 的函式定義指定了一個引數。實際上,方法的特殊之處就在於例項物件會作為函式的第一個引數被傳入。

5.self

就像上面所說,類的方法與普通的函式只有一個特別的區別 —— 它們必須有一個額外的第一個引數名稱(對應於該例項,即該物件本身),按照慣例它的名稱是 self。在呼叫方法時,我們無需明確提供與引數 self 相對應的引數。

簡單來說self就是在未建立例項時,代替例項本身。

同時 self 在定義方法的時候必須有,呼叫方法的時候要忽略。因為呼叫方法時例項已經產生,應當使用建立的例項而非self。

6.共有和私有

python中定義私有變數只要在變數前加兩個下劃線"__".

class Sheep:
    a = 10
    __b = 11

    def sb(self):
        print(self.a)
        print(self.__b)
x = Sheep()
x.sb()
print(x.a)
print(x.__b)
#10
#11
#10
#AttributeError: 'Sheep' object has no attribute '__b'

當我們呼叫方法時能夠輸出私有變數,而想在方法外引用就會報錯,我們輸出x.__b就會報錯,表示例項沒有這個變數。

私有方法同上,想呼叫私有方法,只能在公有方法中引用。

7.繼承
(1)繼承的定義

被繼承的類稱為父類,繼承的類稱為子類

子類會自動繼承父類的方法和屬性。

class Person(object):   # 定義一個父類
    a = 1
    def talk(self):    # 父類中的方法
        print("person is talking....")  
 
 
class Chinese(Person):    # 定義一個子類,繼承Person
 
    def walk(self):      # 在子類中定義其自身的方法
        print('is walking...')
 
c = Chinese()
c.talk()      # 呼叫繼承的Person類的方法
c.walk()     # 呼叫本身的方法
print(c.a)
# 輸出
 
person is talking....
is walking...
1
(2)對子類方法的重構

如果子類中定義與父類同名的方法或屬性,則會自動覆蓋父類的該方法或屬性

class Person(object):  # 定義一個父類
    def __init__(self):
        print("is a person")
    def talk(self):  # 父類中的方法
        print("person is talking....")

class Chinese(Person):
    def __init__(self):
        print("is a Chinese person")
    def walk(self):
        print('is walking...')
c = Chinese()
c.talk()
c.walk()
#is a Chinese person
#person is talking....
#is walking...

要想在父類的一個方法的基礎上增加新功能,可以在同名方法下再次引用父類方法:

def __init__(self):
     Person.__init__(self)
     print("is a Chinese person")
#is a person
#is a Chinese person
#person is talking....
#is walking...

或者使用super()函式:

def __init__(self):
     super().__init__()
     print("is a Chinese person")
#is a person
#is a Chinese person
#person is talking....
#is walking...
(3)新增方法和屬性

子類可以新增其他新方法和屬性

新增屬性:

class Person:
    def __init__(self,name):
        self.name = name
    def information(self):
        print(f"my name is {self.name}")

class Chinese(Person):
    def __init__(self,name,language):
        super().__init__(name)
        self.language = language
    def information(self):
        print(f"my name is {self.name} and I speak {self.language}")
a = Chinese("小明","Chinese")
a.information()
#my name is 小明 and I speak Chinese

新增方法只要在子類中直接加入就可以了。

(4)判斷是否為子類

運用issubclass()函式,有兩個待填形參,前一個填子類,後一個填父類,類是自身的子類。

class A:
    pass
class B(A):
    pass
print(issubclass(B, A))  # True
print(issubclass(B, B))  # True
print(issubclass(A, B))  # False
print(issubclass(B, object))  # True

python中還支援多重繼承,但是容易引起混亂所以一般不使用。

8.組合

類之間除繼承外,還可以相互引用,進行組合,使在一個類中使用其他類。

class Turtle:
    def __init__(self, x):
        self.num = x

class Fish:
    def __init__(self, x):
        self.num = x

class 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條