Day27~30-类

来源:互联网 发布:再生人的骗局知乎 编辑:程序博客网 时间:2024/06/12 00:52
1 新式类和经典类

  查看父类信息的方法

类名.__bases__

  在Python3中默认是新式类, 不管写不写继承

  Python2中默认是经典类, 不继承任何, 父类为空

>>> class A:...     pass...>>> A.__bases__()

  如果要定义新式类, 需要手动写入继承object

>>> class A:...     pass...>>> A.__bases__()

2 类的定义

  定义格式为:

class 类名(父类列表):    类体

  其中类名首字母一般大写

  父类可以有多个, Python支持多继承

3 类和对象

  类体中可以直接写入变量, 这是类的属性, 类和对象都可以调用该属性

  类体中可以定义函数, 此函数第一个参数始终是self, 用于给对象绑定方法

  其中有个特殊函数是 __init__(self, 参数列表)

    该函数在生成对象的时候会调用该方法, 且参数列表需要一一对应

  查看类的名称空间

类名.__dict__

  基本的定义情况

class Student:    country = 'China'    def __init__(self, ID, NAME, SEX, PROVINCE):        self.id = ID        self.name = NAME        self.sex = SEX        self.province = PROVINCE    def getScore(self):        print(self.score)    def setScore(self, score):        self.score = scores1 = Student('000', 'weihuchao', 'male', 'chongqing')print( s1.name )s1.setScore(100)s1.getScore()Student.getScore(s1)print( id(Student.getScore ) )print( id(s1.getScore ) )

  类的作用

    1) 生成对象

对象名 = 类名(参数列表)

    2) 属性引用

类名.类属性#或者类名.函数(类的对象, 参数列表)

  对象的作用

    调用属性和绑定方法

    其中类的函数和对象的方法是不一样的, 尽管事实上实现的功能一致

    对象会先找自己空间是否有属性, 没有就会调用类中的

    如果实赋值语句, 则会绑定一个新的属性

    解除绑定用del

4 继承

  继承会继承父类所有公开的属性和方法

  Python支持多继承

  Python3的多继承查找是c3算法, 可以使用__mro__查看顺序

类名.__mro__

  python2中经典类的多继承查找是 深度优先算法

5 组合和派生

  组合是在绑定属性的时候使用别的类的对象

  派生就是继承之后绑定新的属性和方法

6 接口和抽象类

  接口是光定义函数不实现

  但是无法限制子类继承的时候必须实现那些方法

  要实现限制子类必须实现那些方法, 可以定义一个抽象类

  抽象类是导入abc模块来实现

    需要继承内写入 metaclass=abc.ABCMeta

    给方法加入装饰器 abc.abstractmethod

  具体实现如下

import abcclass Animal(metaclass=abc.ABCMeta):    tag='123123123123123'    @abc.abstractmethod    def run(self):        pass    @abc.abstractmethod    def speak(self):        passclass People(Animal):    def run(self):        pass    def speak(self):        passpeo1=People()print(peo1.tag)

7 super的写法

  在继承的时候, 可能会调用父类的方法, 但是由于python可以多继承, 所以直接指定父类来调用函数容易出现多种问题

  所以在调用父类方法的时候使用super方法

  格式如下

super(当前类名, self).__init__(参数列表)

  具体实例为

class People:    def __init__(self,name,sex,age):        self.name=name        self.age=age        self.sex=sex    def walk(self):        print('父类的walk()')class Chinese(People):    country='China'    def __init__(self,name,sex,age,language='Chinese'):        super(Chinese,self).__init__(name,sex,age)        self.language=language    def walk(self):        super(Chinese, self).walk()        print('子类的walk()')

8 多态

  父类引用指向子类对象

  具体就是 将子类的对象当做参数传入, 传入给他的父类对象, 用父类对象去调用方法, 实际上是调用的子类的方法而不是父类的方法

  具体实例如下

class Animal:    def run(self):         print('动物正在走')   class People(Animal):    def run(self):        print('人正在走')class Pig(Animal):    def run(self):        print('pig is walking')class Dog(Animal):    def run(self):        print('dog is running')def func(obj):    obj.run()

9 封装

  在类中, 可以通过将名字在前面加上__(双下划线)来标识这是私有变量

  在类中, 可以通过 __属性名 来调用该属性  

  在类外, 无法通过 __属性名 就找到该属性

  事实上, 改变了在定义后该变量名字会变成 _类名__属性名 

  但是不建议通过这样的方法来调用该参数

  因而正常情况下, 会编写一个调用该属性的方法当做对外的接口

  具体实例如下

class Student:    def __init__(self, ID, NAME):        self.__id = ID        self.__name = NAME            def getId(self):        print(self.__id)    def setId(self, ID):        self.__id = ID        def getName(self):        print(self.__name)    def setName(self, NAME):        self.__name = NAME

10 使用property

  有的类里面可以通过函数来返回相关的属性值, 比如圆类中, 可以计算周长和面积

  但是这样的用户体验并不好, 我们希望直接通过 调用属性的形式来访问 这个样的属性值, 此时就可以是用装饰器property

  @property装饰器下的函数名, 可以通过 类名.函数名 直接获得该返回值

  具体实现代码如下

import mathclass Circle:    def __init__(self,radius):        self.radius=radius    @property    def area(self):        return math.pi * self.radius**2    @property    def perimeter(self):        return 2*math.pi*self.radiusc=Circle(7)print( c.area )print( c.perimeter )

  @property只是获取属性, 还可以通过更多的装饰器来形成类似的 设置属性, 删除属性等

  设置属性的装饰器是 @函数名.setter

  删除属性的装饰器是 @函数名.deleter

  获得属性的装饰器是 @函数名.getter (这个的存在就覆盖了@property)

11 静态方法和类方法

  静态方法是使用 装饰器staticmethod来形成的函数

  该函数的特点是不需要写入self, 后面的参数列表是正常的参数列表, 而且调用的时候需要一一对应

  因而该函数也不会绑定给对象, 而是属于类的属性函数

  具体情形如下

class Foo:    @staticmethod    def spam(x,y,z):        print(x,y,z)print(Foo.spam)print(Foo().spam)# <function Foo.spam at 0x0000000000B12620># <function Foo.spam at 0x0000000000B12620>

  类方法是使用装饰器classmethod

  类方法就是将方法绑定给类

  类方法第一个参数始终是cls, 代表调用它这个函数的对象的类传入给cls

  具体使用如下

class Foo:    @classmethod    def test(cls, x, y):        print(cls, x, y)Foo.test(1,2)Foo().test(1,2)# <class '__main__.Foo'> 1 2# <class '__main__.Foo'> 1 2

  静态方法和类方法可以相互搭配, 形成很好的效果

import timeclass Date:    def __init__(self,year,month,day):        self.year=year        self.month=month        self.day=day    @classmethod    def now(cls):        t=time.localtime()        obj=cls(t.tm_year,t.tm_mon,t.tm_mday)        return obj    @classmethod    def tomorrow(cls):        t=time.localtime(time.time()+86400)        return cls(t.tm_year,t.tm_mon,t.tm_mday)class EuroDate(Date):    def __str__(self):        return '年:%s,月:%s,日:%s' %(self.year,self.month,self.day)print( EuroDate.now() )# 年:2017,月:4,日:21

  

  

0 0
原创粉丝点击