天天看點

Python 面向對象

Python 總目錄連結

面向對象三大特性-封裝:

封裝,顧名思義就是将内容封裝到某個地方,以後再去調用被封裝在某處的内容。

是以,在使用面向對象的封裝特性時,需要:

  • 将内容封裝到某處
  • 從某處調用被封裝的内容

1、将内容封裝到某處。

class Foo:

    def __init__(self,name,age): # 構造方法,建立對象時自動執行。
        self.name = name
        self.age = age

# 建立對象,self = 對象本身
obj1 = Foo("steven",28)  # 自動執行__init__方法,将 steven,28分别分裝到 name,age中,儲存在記憶體中
obj2 = Foo("author",28)  # 自動執行__init__方法,将 author,28分别分裝到 name,age中,儲存在記憶體中
      

 2、調用。

  • 通過對象直接調用
class Foo:

    def __init__(self,name,age): # 構造方法,建立對象時自動執行。
        self.name = name
        self.age = age

# 建立對象,self = 對象本身
obj1 = Foo("steven",28)  # 自動執行__init__方法,将 steven,28分别分裝到 name,age中
obj2 = Foo("author",28)  # 自動執行__init__方法,将 author,28分别分裝到 name,age中

print obj1.name,obj1.age
print obj2.name,obj2.age
      

 通過self簡介調用

class Foo:

    def __init__(self,name,age): # 構造方法,建立對象時自動執行。
        self.name = name
        self.age = age

    def fun1(self):
        print self.name
        print self.age

# 建立對象,self = 對象本身
obj1 = Foo("steven",28)  # 自動執行__init__方法,将 steven,28分别分裝到 name,age中
obj2 = Foo("author",28)  # 自動執行__init__方法,将 author,28分别分裝到 name,age中

obj1.fun1()
obj2.fun1()

Python預設會将obj2傳給self參數,即:obj1.detail(obj1),是以,此時方法内部的 self = obj1,即:self.name 是 Steven ; self.age 是 28
      

面向對象三大特性-繼承:

多繼承:

Python的類如果繼承了多個類,那麼其尋找方法的方式有兩種,分别是:深度優先和廣度優先

Python 面向對象
  • 當類是經典類時,多繼承情況下,會按照深度優先方式查找
  • 當類是新式類時,多繼承情況下,會按照廣度優先方式查找
Python 面向對象
Python 面向對象
class D:

    def bar(self):
        print 'D.bar'


class C(D):

    def bar(self):
        print 'C.bar'


class B(D):

    def bar(self):
        print 'B.bar'


class A(B, C):

    def bar(self):
        print 'A.bar'

a = A()
# 執行bar方法時
# 首先去A類中查找,如果A類中沒有,則繼續去B類中找,如果B類中麼有,則繼續去D類中找,如果D類中麼有,則繼續去C類中找,如果還是未找到,則報錯
# 是以,查找順序:A --> B --> D --> C
# 在上述查找bar方法的過程中,一旦找到,則尋找過程立即中斷,便不會再繼續找了
a.bar()

經典類多繼承      

經典類繼承

Python 面向對象
Python 面向對象
class D(object):

    def bar(self):
        print 'D.bar'


class C(D):

    def bar(self):
        print 'C.bar'


class B(D):

    def bar(self):
        print 'B.bar'


class A(B, C):

    def bar(self):
        print 'A.bar'

a = A()
# 執行bar方法時
# 首先去A類中查找,如果A類中沒有,則繼續去B類中找,如果B類中麼有,則繼續去C類中找,如果C類中麼有,則繼續去D類中找,如果還是未找到,則報錯
# 是以,查找順序:A --> B --> C --> D
# 在上述查找bar方法的過程中,一旦找到,則尋找過程立即中斷,便不會再繼續找了
a.bar()

新式類多繼承      

新式類多繼承

經典類:首先去A類中查找,如果A類中沒有,則繼續去B類中找,如果B類中麼有,則繼續去D類中找,如果D類中麼有,則繼續去C類中找,如果還是未找到,則報錯

新式類:首先去A類中查找,如果A類中沒有,則繼續去B類中找,如果B類中麼有,則繼續去C類中找,如果C類中麼有,則繼續去D類中找,如果還是未找到,則報錯

注意:在上述查找過程中,一旦找到,則尋找過程立即中斷,便不會再繼續找了

面向對象三大特性-多态:

Python 面向對象
Python 面向對象
class F1:
    pass


class S1(F1):

    def show(self):
        print 'S1.show'


class S2(F1):

    def show(self):
        print 'S2.show'

def Func(obj):
    print obj.show()

s1_obj = S1()
Func(s1_obj) 

s2_obj = S2()
Func(s2_obj)       

View Code

普通字段和靜态字段

class Too:
    # 靜态字段,隻在類裡面儲存
    country = "china"

    # 普通字段
    def __init__(self,name):
        # 普通字段,可以存在對象中
        self.name = name

    # 普通方法
    def show(self):
        print "asf"
      

誰的屬性,誰去通路:即靜态字段盡量類來通路,普通字段盡量對象通路

利用反射檢視面向對象成員歸屬

test.py

class Too:
    # 靜态字段,隻在類裡面儲存
    country = "china"

    # 普通字段
    def __init__(self,name):
        temp = "xxx"
        # 普通字段,對象中
        self.name = name

    # 普通方法
    def show(self):
        print "asf"
      
# 檢視類中是否有show方法
ret1 = hasattr(Too,'show')
# 檢視類中有哪些成員,方法
ret2 = Too.__dict__


#  去對象中找成員或者方法,即在對象找不到,就會找對象的類
obj = Too("steven")
ret3 = hasattr(obj,'name')
ret4 = hasattr(obj,"show")
      
# 導入子產品
m = __import__("test1",fromlist=True)
# 去子產品中找類
class_name = getattr(m,'Too')
# 根據類建立對象
obj = class_name("steven")
# 去對象中找成員
print getattr(obj,'name')



############ 傳回結果 #############
True
{'country': 'china', '__module__': 'test1', '__doc__': None, '__init__': <function __init__ at 0x10177f140>, 'show': <function show at 0x10177f578>}
True
True
steven
      

靜态方法,類方法,property,cls.setter:

class foo:
    """
       規範:靜态方法和靜态字段都由類來通路。
       靜态方法存在的意義,不需要對象就可以通路該方法。
    """
    
    name = "靜态字段"

    # 靜态方法,沒有self,相當于類的方法。
    @staticmethod
    def staticMethod(arg1,arg2):
        print arg1,arg2,"@staticmethod 專門裝飾類中的方法,被裝飾的方法變成了靜态方法"

    def yo(self):
        print "普通方法"

    @classmethod
    def clsMethod(cls):
        print "類方法:%s 通過類來通路"%cls

    @property
    def pro(self):
        ret = "name: %s 以字段的方式通路該方法"% self.name
        return ret

    @pro.setter
    def pro(self,value):
        ret = "設定pro方法。"
        self.name = value
        print self.name

# 通過類調用靜态方法,
foo.staticMethod("class",1)
# 通過對象調用靜态方法, 不推薦。
f = foo()
f.staticMethod("object",2)

# 通過類來通路類方法
foo.clsMethod()

# 調用pro
print f.pro
# 設定pro
f.pro=123      
總結:
成員:
    字段   靜态字段(對象中有重複的字段時用該字段),普通字段(每個對象需要傳輸不通資料的時候用該該字段)
    方法   靜态方法(無需使用對象來調用的時候,即直接當函數調用)、類方法(類似靜态方法,會傳類名)、普通方法(需要用到對象的資料)
    特性   普通特性(将方法僞造成字段) 

判斷什麼時候類執行,什麼時候對象執行:
    self 對象調用
    無self 類調用      

成員修飾符: