Day27~30-类
来源:互联网 发布:再生人的骗局知乎 编辑:程序博客网 时间:2024/06/12 00:52
查看父类信息的方法
类名.__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
- Day27~30-类
- Day27
- day27
- 30天自制操作系统day27
- Summary Day27
- day27笔记
- 《30天精通iPhone手机编程》-Day27-十字方向键
- day27,page50,total200
- 黑马程序员-day27反射
- java学习day27
- 框架 day27 Struts2 入门(概述,基本xml配置,动态方法调用,Action类,ServletAPI访问,结果集)
- 正则表达式 反射(day27)
- Day27:Three People getting cards
- DAY27:leetcode #18 4Sum
- day27-反射&JDK新特性
- 传智播客-Java学习笔记day27
- day27<反射&JDK5新特性>
- day27:Spark on Yarn彻底解密
- 使用new和delete创建二维数组
- 第八章-错误调试
- 001-将Python源码转换为不需要环境的可执行文件
- rxJava学习笔记
- 第九章-IO编程
- Day27~30-类
- Day31-面向对象高级(上)
- 第十章-进程和线程
- Day32-面向对象高级(下)
- FFmpeg源代码简单分析:日志输出系统(av_log()等)
- Day33-常用模块
- ubuntu 安装 nginx php7.0-fpm mysql-server php7.0-mysql
- 002-Fatal error in launcher: Unable to create process using '""
- spring之上传处理