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

 








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