| 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 # 初始化兩個計數器a,b 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 # Sun的value被設定爲0 Mon = 1 Tue = 2 Wed = 3 Thu = 4 Fri = 5 Sat = 6 |
|
| Python | PHP |
元類metaclass 類似php的接口interface
元類不常用,但是在某些時候非常有用 | 類的type爲type類型,對象的type爲class類型 使用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 |
|