面向對象

面向對象格式

定義:
class 類名:                - 定義了一個類                        
    def 函數名(self):        - 在類中編寫了一個"方法"
        pass 
調用:
x1 = 類名()            - 建立了一個對象/實例化一個對象
x1.函數名()            - 經過對象調用其中一個方法

self是什麼

self參數是python幫助咱們傳遞的,調用的是哪一個實例,self就指向誰python

構造方法

__new__(self)構造方法算法

__init__(self)初始化ide

class Foo(object):
    def __init__(self, a1, a2):     # 初始化方法
        """
        爲空對象進行數據初始化
        :param a1:
        :param a2:
        """
        self.a1 = a1
        self.a2 = a2

    def __new__(cls, *args, **kwargs): # 構造方法
        """
        建立一個空對象
        :param args:
        :param kwargs:
        :return:
        """
        return object.__new__(cls) # Python內部建立一個當前類的對象(初創時內部是空的.).
構造方法

方法和函數的區別

寫在類中的函數叫作方法,寫在類外面的就是函數函數

對象.xxx ->>> 方法spa

類.xxx ->>>函數3d

xxx ->>>函數code

打印查看:對象

方法 ->>> methodblog

函數 ->>>function繼承

代碼檢查

from types import MethodType, FunctionType


def check(arg):
    """
    檢查arg是方法仍是函數?
    :param arg:
    :return:
    """
    if isinstance(arg, MethodType):
        print('arg是一個方法')
    elif isinstance(arg, FunctionType):
        print('arg是一個函數')
方法or函數

面向對象的三大特性

封裝

將相關功能封裝到一個類中

class FuncOne:
    def func1(self):
        pass

    def func2(self):
        pass

    def func3(self):
        pass

 

將數據封裝到一個對象中

class FuncTwo:
    def __init__(self, para1, para2, para3):
        self.para1 = para1
        self.para2 = para2
        self.para3 = para3

繼承

爲了實現代碼的複用性

class FuncThree:
    def func1(self):
        pass


class FuncFour(FuncThree):
    def func2(self):
        pass


obj = FuncFour()
obj.func1()

經典類和新式類:

python2:經典類和新式類(object)

python3:只有新式類

經典類的查找順序:深度優先

新式類的查找順序:C3算法(python2.3更新)

注意:super遵循的是__mro__執行順序

多態

類的成員

累的變量

實例變量(字段)

實例變量是類中方法中的變量,調用時須要經過對象

class FuncChange:

    def __init__(self, para1, para2):
        self.para1 = para1
        self.para2 = para2


obj = FuncChange(1,2)
print(obj.para1)

類變量(靜態字段)

寫在類的裏面,類裏的方法外面,調用時經過類名

class ST:
    lst = []

    def get_lst(self):
        self.lst.insert(0,33)
        return self.lst


class TT(ST):
    lst = [11, 22]


s1 = TT()
s2 = TT()
y1 = s1.get_lst()
print(y1)
y2 = s2.get_lst()
print(y2)
print(TT.lst)
注意點
class FuncChange:
    para_one = 123

    def __init__(self, para1, para2):
        self.para1 = para1
        self.para2 = para2


print(FuncChange.para_one)

類的方法

實例方法

類中普通的方法,包含self,經過對象調用

class FuncWay:
    def __init__(self, para1, para2):
        self.para1 = para1
        self.para2 = para2

    # 實例方法
    def func1(self):
        print(self.para1)

obj = FuncWay(1,2)
obj.func1()     # 實例方法調用

靜態方法

@staticmethod,無需使用對象中封裝的值,能夠本身傳參,且不須要self,經過類名執行

class FuncWay:
    def __init__(self, para1, para2):
        self.para1 = para1
        self.para2 = para2

    # 靜態方法
    @staticmethod
    def func2(para3):
        print(para3)

FuncWay.func2(1)     # 靜態方法調用

類方法

@classmethod,包含cls,經過類名執行

class FuncWay:
    def __init__(self, para1, para2):
        self.para1 = para1
        self.para2 = para2

    # 類方法
    @classmethod
    def func3(cls, para4):
        print(cls, para4)

FuncWay.func3(1)     # 類方法調用

類的屬性

經過方法改造而來,@property

只有一個參數self,調用時無需加括號,所以適用於無需傳參且有返回值時使用

class FuncProperty:
    @property
    def func(self):
        return 123


obj = FuncProperty()
print(obj.func)

類的公有與私有

不管是類的變量,類的方法仍是類的屬性都有公有和私有,

公有就是在類的內外均可以調用,私有是隻能在類的內部調用,私有的建立是在命名時在名字前加"__"

class Foo:
    a1 = 1
    __a2 = 2

    def __init__(self, num):
        self.num = num
        self.__salary = 1000

    def data(self):
        print(self.num+self.a1)


obj1 = Foo(666)
obj2 = Foo(999)
print(obj1.num)
print(obj1.a1)

obj1.num = 18
obj1.a1 = 99

print(obj1.num)
print(obj1.a1)

print(obj2.a1)
print(obj2.num+Foo.a1)
print(obj2.num+obj1.a1)
運行結果:
666
1
18
99
1
1000
1098
1
class Foo:
    a1 = 1
    __a2 = 2

    def __init__(self, num):
        self.num = num
        self.__salary = 100

    def data(self):
        print(self.num+self.a1)


obj = Foo(666)
print(obj.num)
print(obj.a1)
print(obj.__salary)
print(obj.__a2)
print(Foo.a1)
print(Foo.__a2)
運行結果:
 666
 1
 Error
 Error
 1
 Error
2
class Base:
    @classmethod
    def f3(cls):
        print(cls)

    def f1(self):
        print("base.f1")
        self.f3()


class Foo(Base):
    def f2(self):
        print("foo.f2")
        self.f1()


obj = Foo()
obj.f2()
運行結果:
foo.f2
base.f1
<class '__main__.Foo'>
3

 類的組合

調用其餘類的成員

經過本身調self

class Base(object):

    def f1(self):
        print('調用了Base')


class Foo(object):

    def f1(self):
        print('我是Foo')
        Base.f1(self)

obj = Foo()
obj.f1()
運行結果:
我是Foo
調用了Base

super,按照繼承的順序找下一個

class Foo(object):
    def f1(self):
        super().f1()
        print('我是Foo')


class Bar(object):
    def f1(self):
        print('我是Bar')


class Info(Foo, Bar):
    pass


obj = Info()
obj.f1()
運行結果:
我是Bar
我是Foo

特殊成員

當對象.屬性沒有時,觸發__getattr__方法

類名()->自動執行__init__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1 self.a2 = a2
  def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2

obj = Foo(1,2)
print(obj.a1 + obj.a2)
運行結果: 
3

對象()->自動執行__call__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1 self.a2 = a2
  def __call__(self, *args, **kwargs):
        print(11111, args, kwargs)
        return 123                              #能夠有返回值

obj = Foo(1,2)
ret = obj(6, 4, 2, k1=456)
print(ret)
運行結果:
11111 (6, 4, 2) {'k1': 456}
123

對象['xx']->自動執行__getitem__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1 self.a2 = a2
  def __getitem__(self, item):
        print(item)
        return 8        #有返回值

obj = Foo(1,2)
ret = obj['wo']
print(ret)
運行結果:
wo
8

對象['xx'] = xx ->自動執行__setitem__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1 self.a2 = a2
  def __setitem__(self, key, value):
        print(key, value, 111111111)
                          #沒有返回值
obj = Foo(1,2)
obj['k'] = "setitem"
運行結果:
k setitem 111111111

del 對象[xx] ->自動執行__delitem__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1 self.a2 = a2
  def __delitem__(self, key):
        print(key)

obj = Foo(1,2)
del obj['wo']
運行結果:
wo

對象+對象 ->自動執行__add__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1 self.a2 = a2
  def __add__(self, other):
        return self.a1 + other.a2

obj = Foo(1,2)
obj1 = Foo(1,2)
obj2 = Foo(88,99)
ret = obj2 + obj1
print(ret)
運行結果:
90

with對象 ->自動執行__enter__/__exit__

class Foo(object):
    
    def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2

    def __enter__(self):
        print('1111')
        return 999

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('22222')

obj = Foo(1,2)
with obj as f:
    print(f)
運行結果:
1111
999
22222
class UserInfo(object):
    pass

class Department(object):
    pass

class StarkConfig(object):

    def __init__(self,num):
        self.num = num

    def changelist(self,request):
        print(self.num,request)

    def run(self):
        self.changelist(999)

class RoleConfig(StarkConfig):

    def changelist(self,request):
        print(666,self.num)

class AdminSite(object):
    def __init__(self):
        self._registry = {}

    def register(self,k,v):
        self._registry[k] = v(k)

site = AdminSite()
site.register(UserInfo,StarkConfig)
site.register(Department,StarkConfig)
print(len(site._registry)) # 3
for k,row in site._registry.items():
    row.run()
組合

 __dict__

用字典反回形參和所傳實參

class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def func(self):
        pass


obj1 = Foo('張三', 19)
obj2 = Foo('李四', 20)


print(obj1.__dict__)
print(obj2.__dict__)
運行結果:
{'name': '張三', 'age': 19}
{'name': '李四', 'age': 20}

__doc__

顯示註釋信息

class Foo(object):
    """
    返回此處的註釋信息
    """
    def __init__(self):
        pass

    def func(self):
        pass

    def __str__(self):
        return "F1"


obj = Foo()
print(obj.__doc__)
運行結果:
返回此處的註釋信息

__str__

打印對象時,顯示的是__str__內的字符串,因此看到str不必定就是str,只有type檢測出的str可信

class Foo(object):
    def __init__(self):
        pass

    def func(self):
        pass

    def __str__(self):
        return "F1"


obj = Foo()
print(obj, type(obj))
運行結果:
F1    <class '__main__.Foo'>

__iter__

將不可迭代對象變爲可迭代對象

class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def func(self):
        pass

    def __iter__(self):
        return iter([11, 22, 33])

obj = Foo("張三", 18)
for el in obj:
    print(el)
運行結果:
11
22
33
1
class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def func(self):
        pass

    def __iter__(self):
        yield 11
        yield 22
        yield 33


obj = Foo("張三", 18)
for el in obj:
    print(el)
運行結果:
11
22
33
2 

issubclass,type,isinstance

issubclass

檢查第一個參數是不是第二個參數的子孫類

class Base(object):  #
    pass


class Foo(Base):  #
    pass


class Bar(Foo):  #
    pass


print(issubclass(Bar, Base))
print(issubclass(Bar, Foo))
運行結果:
True
True
issubclass 

type

獲取當前對象是由那個類建立的

class Foo(object):
    pass


obj = Foo()
print(obj, type(obj))  
if type(obj) == Foo:
    print('obj是Foo類型')
運行結果:
<__main__.Foo object at 0x00000000021EB9E8> 
<class '__main__.Foo'>
obj是Foo類型
type

isinstance

檢查第一個參數(對象)是不是第二個參數(類及父類)的實例

class Base(object):
    pass


class Foo(Base):
    pass


class Tuu:
    pass


obj1 = Foo()
print(isinstance(obj1, Foo))
print(isinstance(obj1, Base))
print(isinstance(obj1, Tuu))
運行結果:
True
True
False
isinstance

 反射

getattr

根據字符串的形式,去對象中找成員

if hasattr(handler,val):
    func_or_val = getattr(handler,val)     # 根據字符串爲參數,去模塊中尋找與之同名的成員。
    if isinstance(func_or_val,FunctionType):
        func_or_val()
else:
    print(func_or_val)
from types import MethodType,FunctionType
def func(i):
    if isinstance(i, MethodType)
        print("這是方法")
    elif isinstance(i, FunctionType)
        print("這是函數")

hasattr 

根據字符串的形式,去判斷對象中是否有成員

setattr 

根據字符串的形式,動態的設置一個成員到內存中

delattr 

根據字符串的形式,動態的刪除一個成員(內存中)

 

class Foo(object):

    def __init__(self):
        object.__setattr__(self, 'info', {})  # 在對象中設置值的本質

    def __setattr__(self, key, value):
        self.info[key] = value

    def __getattr__(self, item):
        print(item+"123")
        return self.info[item]


obj = Foo()
obj.name = 'sb'
print(obj.name)
View Code
相關文章
相關標籤/搜索