python中多重繼承與獲取對象


1、python中多重繼承

除了從一個父類繼承外,Python允許從多個父類繼承,稱為多重繼承。

多重繼承的繼承鏈就不是一棵樹了,它像這樣:

class A(object):
    def __init__(self, a):
        print 'init A...'
        self.a = a

class B(A):
    def __init__(self, a):
        super(B, self).__init__(a)
        print 'init B...'

class C(A):
    def __init__(self, a):
        super(C, self).__init__(a)
        print 'init C...'

class D(B, C):
    def __init__(self, a):
        super(D, self).__init__(a)
        print 'init D...'

看下圖:

像這樣,D 同時繼承自 B 和 C,也就是 D 擁有了 A、B、C 的全部功能。多重繼承通過 super()調用__init__()方法時,A 雖然被繼承了兩次,但__init__()只調用一次:

>>> d = D('d')
init A...
init C...
init B...
init D...

多重繼承的目的是從兩種繼承樹中分別選擇並繼承出子類,以便組合功能使用。

舉個例子,Python的網絡服務器有TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer,而服務器運行模式有 多進程ForkingMixin 和 多線程ThreadingMixin兩種。

要創建多進程模式的 TCPServer:

class MyTCPServer(TCPServer, ForkingMixin)
    pass

要創建多線程模式的 UDPServer:

class MyUDPServer(UDPServer, ThreadingMixin):
    pass

如果沒有多重繼承,要實現上述所有可能的組合需要 4x2=8 個子類。

2、python獲取多重對象

拿到一個變量,除了用 isinstance() 判斷它是否是某種類型的實例外,還有沒有別的方法獲取到更多的信息呢?

例如,已有定義:

class Person(object):
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender

class Student(Person):
    def __init__(self, name, gender, score):
        super(Student, self).__init__(name, gender)
        self.score = score
    def whoAmI(self):
        return 'I am a Student, my name is %s' % self.name

首先可以用 type() 函數獲取變量的類型,它返回一個 Type 對象:

>>> type(123)
<type 'int'>
>>> s = Student('Bob', 'Male', 88)
>>> type(s)
<class '__main__.Student'>

其次,可以用 dir() 函數獲取變量的所有屬性:

>>> dir(123)   # 整數也有很多屬性...
['__abs__', '__add__', '__and__', '__class__', '__cmp__', ...]

>>> dir(s)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'gender', 'name', 'score', 'whoAmI']
對於實例變量,dir()返回所有實例屬性,包括`__class__`這類有特殊意義的屬性。注意到方法`whoAmI`也是 s 的一個屬性。

如何去掉`__xxx__`這類的特殊屬性,只保留我們自己定義的屬性?回顧一下filter()函數的用法。

dir()返回的屬性是字符串列表,如果已知一個屬性名稱,要獲取或者設置對象的屬性,就需要用 getattr() 和 setattr( )函數了:

>>> getattr(s, 'name')  # 獲取name屬性
'Bob'

>>> setattr(s, 'name', 'Adam')  # 設置新的name屬性

>>> s.name
'Adam'

>>> getattr(s, 'age')  # 獲取age屬性,但是屬性不存在,報錯:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'age'

>>> getattr(s, 'age', 20)  # 獲取age屬性,如果屬性不存在,就返回默認值20:
20

實例:

class Person(object):

def __init__(self, name, gender, **kw):
self.name = name
self.gender = gender
self.__dict__.update(kw)

p = Person('Bob', 'Male', age=18, course='Python')
print (p.age)
print (p.course)

結果:
18
Python
 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM