Python_day6:面向對象

 

Python

PHP

面向對象

繼承、封裝、多態

 

方法的動態綁定

class Student(object):

    pass

 

obj = Student()

obj.name = "zhaohuiqi"

print(obj.name)

 

def set_age(self,age):

    self.age = age

#對象綁定

from types import MethodType

obj.set_age = MethodType(set_age,obj)

obj.set_age(26)

print(obj.age)

#類綁定

Student.set_age = set_age

 

__slots__

新增屬性限制

__slots__限制只對當前類對象生效,對子類不生效,

如果在子類也設置了__slots__,那麼子類的限制爲父類+子類的限制

__slots__ = () 不做限制

限制類允許綁定的屬性和方法,字符串表示

class Student(object):

    __slots__ = ('name','age','set_age')

    pass

 

@property

把一個方法變成屬性調用

class Student(object):

    @property

    def score(self):

        return self._score

 

    @score.setter

    def score(self,value):

        if not isinstance(value, int):

            raise ValueError('score must be an integer!')

        if value < 0 or value > 100:

            raise ValueError('score must between 0 ~ 100!')

        self._score = value

 

student = Student()

student.score = 28

print(student.score)

如果一個方法之設置的@property,不設置setter,那就是一個只讀屬性

 

 

Python

PHP

多繼承

支持多繼承,逗號隔開

class Bat(Mammal, FlyableMixIn):

    pass

額外功能的父類命名一般使用XxxMixIn

 

不支持多繼承,可以鏈式繼承

定製類

__xxx__系列

 

__str__

直接打印對象的時候控制返回值,可以打印出一個方便識別的字符串

class Student(object):
    def __init__(self,name):
        self.name = name
  
    def __str__(self):
        return 'Student object (name: %s)' % self.name
  
s = Student('tony')
  print(s)

 

__repr__

調試用輸出,調用的時候還是返回原來的對象寫法

可以使用__repr__ = __str__來使兩個打印內容一致

 

__iter__

配合__next__使用

對象中存在想要迭代的對象for i in Student()

class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1 # 初始化兩個計數器ab
  
    def __iter__(self):
        return self # 實例本身就是迭代對象,故返回自己
  
    def __next__(self):
        self.a, self.b = self.b, self.a + self.b # 計算下一個值
        if self.a > 100000: # 退出循環的條件
            raise StopIteration()
        return self.a # 返回下一個值
  for i in Fib():
    print(i)

 

__getitem__

將一個對象當成list使用

class Fib(object):
    def __getitem__(self, n):
        a, b = 1, 1
        for x in range(n):
            a, b = b, a + b
        return a
  print(Fib()[4])

 

這樣處理並不能使用list切片等功能,還需要進一步處理

 

 

Python

PHP

__getattr__

當調用一個不存在的屬性,不處理的時候會報錯,設置後可以進行控制

class Student(object):
  
    def __init__(self):
        self.name = 'Michael'
  
    def __getattr__(self, attr):
        return 'Not Exist'
  s = Student()
  print(s.score)

返回值可以自行控制,返回函數也可以

def __getattr__(self, attr):
    if attr == 'score':
        return lambda: 90
    raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)

在想要進行個別屬性控制的時候這樣處理

 

__call__

將對象直接作爲方法進行調用

class Student(object):
    def __init__(self, name):
        self.name = name
  
    def __call__(self):
        print('My name is %s.' % self.name)
s = Student('tony')
s()

 

callable()函數可以判斷一個對象是否可以進行調用

 

 

Python

PHP

枚舉enum

from enum import Enum
  
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
  
  for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)

枚舉的訪問方式

print(Month(1))
  print(Month['Jan'])

value默認從1開始:int

自定義value的枚舉

from enum import Enum, unique
  
  @unique
  class Weekday(Enum):
    Sun = 0 # Sunvalue被設定爲0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

 

 

Python

PHP

元類metaclass

類似php的接口interface

 

元類不常用,但是在某些時候非常有用

類的typetype類型,對象的typeclass類型

使用type()函數進行類的動態創建(不常用

def fn(self, name='world'): # 先定義函數
    print('Hello, %s.' % name)
Student = type('Student',(object,),dict(hello=fn))
  
s = Student()
s.hello()

 

metaclass作爲元類必須是type派生出來的

class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
        attrs['add'] = lambda self, value: self.append(value)
        return type.__new__(cls, name, bases, attrs)
  
  class MyList(list, metaclass=ListMetaclass):
    pass
  
  L = MyList()
L.add(1)
  print(L)

在創建類的時候傳入關鍵字metaclass就可以直接指向__new__

參數爲類名name,父類bases,方法集合attr

 








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章