| 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 |
|