python学习之-- 面向对象
面向对象(简写:OOP)
面向对象编程定义:利用类和对象来创建各种模型,来实现对真实世界的描述。
优点:使程序更容易理解和维护以及扩展代码。
类定义:用来描述具有相同的属性和方法的对象的集合。(简单讲就是个模板)
实例化定义:创建一个类的实例,类的具体对象。
对象定义:通过类定义的数据结构的实例
举例:一个最简单最小结构的类写法如下:
class class_name(object):
print('bababa')
举例一个正常类的写法:
class 类名称(object):
def __init__(self,name..) #构造函数
self.arg1 = name # 普通属性(成员变量),注:self就是实例对象本身,保存在对象内存里
def fun1(self): # 普通方法(动态属性)
print('...')
类进行实例化的运行原理:
1:将类中的对象和方法存储于内存中,
2:类进行实例化时,先在内存申请一块空间用于存放实例对象
3:把实例对象的内存地址和赋值参数传递给类模板
4:模板对传入的值进行self变量赋值,然后将self变量发送到实例对象内存空间。
类的三大特性:封装,继承,多态
-- 封装:类内部的数据和方法,对数据的赋值和内部调用对类外部而言是透明的。简单说就是隐藏实现的细节,使代码模块化。
特性:防止数据被随意修改,可以通过此对象对外接口进行直接访问。
另(类封装了属性和方法,对象封装了普通属性的值)
-- 继承:一个父类派生出的子类,在父类里定义的属性和方法自动被子类继承,实现一个角色的共同点和不同点的同时存在。使代码重用
注意:承可以多级继承,不过越多代码会越复杂,建议继承2-3级即可,继承的2个类之间应该是属于的关系。
-- 被继承的类命名:父类,基类,超类
-- 继承的类命名:子类,派生类
--种类:单继承和多继承。
--继承的过程:从一般到特殊的过程。
这里“一般”指:父类这样的对一个角色具有共同点。
这里“特殊”指:子类这样的对每一个角色的不同点的单独定义
--实现方式有2类:实现继承 和 接口继承
实现继承:指父类具有的功能,子类继承后直接调用不需再修改。
接口继承:指仅使用父类的属性和方法的名称,具体实现需要在子类里单独实现。
举例:单继承基本继承写法
class Person(object):
def __init__(self,name,age=22):
self.NAME = name
self.AGE = age
self.storage = 'Normal'
def talk(self):
print('custom ......')
class blackPerson(Person):
def __init__(self,name,age,job):
Person.__init__(self,name,age) #继承父类的属性(经典写法)
self.JOB = job
def talk(self):
Person.talk(self) # 继承父类的方法,不过这样没有意义,
print('非洲语言')
class writePerson(Person):
def __init__(self,name,mess):
Person.__init__(self,name)
self.MESS = mess
def talk(self):
print('speak ENGLISH')
-- 多态:同样的方法名的同时又对父类的方法做了不同的实现,这就是同一事务表现的多种形态。特点接口重用。
(举例:父类定义人会说话,子类分黄种人说汉语,白种人说英语)这就是多态。实现是改写父类的talk方法
举例:python中多态的写法
class Animal(object):
def __init(self,name):
self.name = name
def talk(self):
raise NotImplementedError('Subclass must implement abstrace method') #提示一个需要子类重写的错误
class Cat(Animal):
def talk(self): # 子类重写
return 'miao'
class dog(Animal):
def talk(self): # 子类重写
return 'wang'
d = dog()
c = Cat()
def animal_talk(arg): # 这里使用单独一个函数实现多态功能
return arg.talk()
print(animal_talk(d))
print(animal_talk(c))
类的属性分如下:
-- 公有属性(静态字段):所有属于这个类的对象都可以访问的属性,(在类里直接定义的属性,class下一行定义的)
修改方法:1:通过对象修改,只改变该对象的属性值,相当于在对象本地内存新创建一个属性值(默认是引用类里的全局变量)
2:通过“类.公有属性名”修改,将改变的是全局属性值。
(疑问解释:类中的构造函数不都可以访问么,说的是实例对象,一个实例对象赋给的参数值在其他对象是无法访问的。所以构造函数不属于公有属性。
比如:实例化了2个对象a,b,其中实例化a的参数值(a=fun(1,2,3)),对象b就无法访问a的参数值。)
--成员属性(普通字段):构造函数中的self变量。
--私有属性:在类中以“__字符串”,双下划线开始的变量名即为私有属性。正常情况下私有属性在类外部是无法访问的。
访问方法有2种:1:通过在类里定义普通方法来return返回私有属性。2:强制访问写法:实例名._类名__私有属性名。
举例:使用第一个方法对外提供私有属性访问接口
def get_hart():
return self.__heart #这里就直接返回私有属性值
类的方法分如下:
-- 普通方法:类中定义的常用方法。def定义的
小知识(如何将普通方法变为私有方法,1:单独写一个函数,比如名为fun2,然后重写对象的方法名,如d1.fun = fun2,最后执行此对象的方法d1.fun(d1))
-- 析构方法:语法:def __del__(self),在引用的变量被清空的时候或者通过手工del删除引用的变量后就会自动调用此方法进行内存回收。
一般用于程序的收尾,比如服务器端要停止服务,这时就需要它来清空客户端的连接。(另说明,只要类被实例化了就算是使用中,将不会自动回收)
-- 类方法:只能访问类变量(公有属性),不能访问实例变量,一般用在实例化对象后,无法对本身限定好的数据进行修改。
举例说明:
class f1:
name = 'jack' #类变量
@classmethod #类方法
def fun(self):
print('classmethod %s' % self.name) # 这里数据只用使用name的值,无法修改
-- 静态方法:类里定义的方法,当不需要通过self往里传值的时候,就可以将此方法定义为静态方法。
举例说明:
class f1:
@staticmethod # 静态方法写法
def fun(): # 注意 静态方法是不需要self传值,这里不写self
print('staticmethod')
调用方法为: f1.fun()
-- 属性方法:把一个方法变成一个静态属性,属性就不需要加括号调用,一般用于最终展示给用户看得结果
举例说明:
class f1:
def __init__(self):
self.__food = None # 为属性方法设置的私有属性(用于传值的,如果不使用setter方法,就可以不写)
@property #属性方法 (静态属性)默认这里只能打印固定数据,无法赋值
def fun(self): # 方法名
print('property: %s' % self.name,self.__food)
@fun.setter # 实现对属性方法赋值功能(注意这里的fun要和上面的方法名一致)
def fun(self,food):
print('set to food:',food)
self.__food = food # 实现对私有属性的赋值
@fun.deleter # 实现删除属性方法的赋值
def fun(self):
del self.__food # 删除私有变量
调用方法:d = f1() ; d.fun # 打印属性方法
赋值方法:d.fun = 'baozi' # 赋值
删除赋值:del d.fun #删除
-- 内置方法:类里以:__名称__ 这样结构的方法称为类的内置方法。
1:__doc__:类的描述信息,就是打印类名下的注释信息
2:__module__:表示当前操作的对象在哪个模块
__class__:表示当前操作的对象的类名
3:__init__:构造函数,通过类创建对象时,自动触发执行。
4:__del__:析构函数,当对象在内存中被释放时,自动触发。
5:__call__:对象后面加括号,触发执行。
举例说明:
class cla1(object):
def __call__(self, *args, **kwargs):
print(args,kwargs)
ins = cla1()
ins('jace','vivi',name='jack',age=22) # 这里执行对象直接返回
返回:('jace', 'vivi') {'name': 'jack', 'age': 22}
6:__dict__:查看类或对象中的所有成员
print(类名.__dict__):打印类里的所有属性,不包括实例属性。print(实例名.__dict__):打印实例里所有的属性,不包括类属性
7:__str__:如果一个类中定义了此方法,那么在打印实例对象时,默认输出该方法的返回值
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __str__(self):
return '(Person: %s, %s)' % (self.name, self.gender)
现在,在交互式命令行下用 print 试试: >>> p = Person('Bob', 'male')
>>> print p
(Person: Bob, male)
8:__repr__:在python3里发现直接运行实例和使用pring 输出的状态和__str__ 相同。没看出有什么区别。但是通过sqlalchemy的创建表结构里可以看出区别,
通过在表结构里定义__str__返回来的数据是内存对象,通过在表结构里定义__repr__返回来的是转换后的字符串。
9:__getitem__ / __setitem__ / __delitem__ :用于索引操作,分别表示获取,设置,删除数据。
举例说明:
class cla1(object):
def __init__(self):
self.data = {}
def __getitem__(self, key):
print("__getitem__: %s" % key)
return self.data.get(key)
def __setitem__(self, key, value):
print('__setattr__:%s,%s' % (key,value))
self.data[key] = value
def __delitem__(self, key):
print('__delitem__:%s' % (key))
ins = cla1()
ins['name'] = 'jack' #调用setitem赋值
print(ins['name']) # 调用getitem打印
print(ins.data) # 打印实例属性
10:__new__:先于构造函数执行,构造函数是通过New来自动执行的。所以new是用来创建实例的,默认不用写
用处:可以在类进行实例化之前,通过new进行定制
class foo(object):
def __init__(self,name):
self.name = name
print('foo --init--')
def __new__(cls, *args, **kwargs):
print('foo --new--')
return object.__new__(cls) # 继承父类的new方法,如果注销这个,将不会自动执行构造函数,
#以上这行解释,类foo也是一个对象,这里的cls就是foo对象本身,也就相当于self概念。
f = foo('jack')
11:__metaclass__ : 指定当前类的原类名称,可以修改原类对当前类进行重新设置。在上面的new执行之前,
执行顺序为:第一步执行metaclass的init方法,第二步执行metaclass的call方法,第三步执行foo函数的new方法,第四步执行foo的initd方法,
这就是实例化整个路线图。
看代码:
class Mytype(type):
def __init__(self): #第一步
super(Mytype.self).__init__(what,bases,dict)
def __call__(self,*args,**kwargs): #第二步
.....
class foo(object):
__metaclass__ = 'Mytype'
def __init__(self,..): # 第四步 实例化完成
.....
def __new__(cls,*args,**kwargs):
return object.__new__(cls) #第三步
看图:
类的 分类:有2种,第一种是:新式类。第二种是:经典类
-- 他们的区别:1:新式类需要在类名后加(object),经典类不需要,直接定义类名。2:继承方式写法不同。
-- 继承方式:在Python3中全部(新式类/经典类)为广度优先,在Python2中经典为深度优先,新式类为广度优先。
-- 继承写法:新式类使用super,经典类直接使用父类名初始化。
举例说明:
class A(object):
def __init__(self):
self.n = 'A'
class B(A):
def __init__(self):
self.n = 'B'
class C(A):
def __init__(self):
self.n = 'C'
class D(B,C):
pass
mess = fun4() ; print(mess.n)
解释:在python3中,无论是新式类还是经典类,继承顺序都是广度优先,以上顺序为:B->C-A
在python2中,新式类继承顺序为广度优先,如上,经典类是深度优先为:B->A->C
举例单独说明类中的self。(self == 实例对象)
class dog(object):
def __init__(self,name):
self.NAME = name
def sayhi(self):
print('wang wang wang , dog name %s' % (self.NAME))
dg1 = dog('jinba') # 相当于:dog(dg1,'jinba') 注意:self == dg1(实例对象)
dg1.sayhi() # 就相当于:dg1.sayhi(dg1),因为self在类中默认是传入的。
python学习之-- 面向对象的更多相关文章
- Python学习之==>面向对象编程(二)
一.类的特殊成员 我们在Python学习之==>面向对象编程(一)中已经介绍过了构造方法和析构方法,构造方法是在实例化时自动执行的方法,而析构方法是在实例被销毁的时候被执行,Python类成员中 ...
- Python学习一(面向对象和函数式编程)
学习了一周的Python,虽然一本书还没看完但是也收获颇多,作为一个老码农竟然想起了曾经荒废好久的园子,写点东西当做是学习笔记吧 对Python的语法看的七七八八了,比较让我关注的还是他编程的思想,那 ...
- 从0开始的Python学习014面向对象编程
简介 到目前为止,我们的编程都是根据数据的函数和语句块来设计的,面向过程的编程.还有一种我们将数据和功能结合起来使用对象的形式,使用它里面的数据和方法这种方法叫做面向对象的编程. 类和对象是面向对象 ...
- python学习 day23 面向对象三大特性之继承
### 面向对象三大特性值继承#### 1.什么是继承 继承是一种关系,必须存在两个对象才可能产生这种关系,在现实生活中的继承,王思聪可以继承王健林的财产 被继承的成为父,继承的一方成为子 在程序中, ...
- Python学习-day6 面向对象概念
开始学习面向对象,可以说之前的学习和编程思路都是面向过程的,从上到下,一步一步走完. 如果说一个简单的需求,用面向过程实现起来相对容易,但是如果在日常生产,面向对象就可以发挥出他的优势了. 程序的可扩 ...
- Python学习之面向对象基础
python的面向对象和以前学的c++,Java都是一般,大同小异,面向对象基础先谈谈类的构造,编写,属性和方法的可见性等等 1.定义类,创建和使用对象 #定义类 class Student(obje ...
- Python学习--10 面向对象编程
面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 本节对于面向对象的概念不做 ...
- python学习总结(面向对象进阶)
-------------------类属性和实例属性关系------------------- 1.类属性和实例属性关系 1.实例属性 实例对象独有的属性 2.类属性 ...
- python学习day19 面向对象(一)封装/多态/继承
面向对象 封装思想:将同一类的函数函数封装到同一个py文件中,方便调用 面向对象也有封装的作用,将同一类的函数封装到一个类中 多态(鸭子模型):多种类型/多种形态 #,什么事鸭子模型 对于一个函数,p ...
- python学习笔记----面向对象
面向对象 类:成员变量(属性) 方法(操作成员变量) 出一个场景:玩过游戏.主人公,进入了一个场景,有10个小怪物是一样的.有攻击力,血(100格).如果小怪物有多个数值需要管理,小怪物的血量.小怪物 ...
随机推荐
- php中session实现机制
一.默认机制,用磁盘文件来实现PHP会话.php.ini配置:session.save_handler = files 1.session_start() A. session_start()是ses ...
- tomcat 安全配置文档
1.配置文档中使用$CATALINA_HOME变量声明为tomcat的安装目录并明确写出了tomcat的配置文件路径,此路径为测试环境的路径,线上系统对应配置文件的路径可能不一样,在进行相关配置时,应 ...
- 图片充当li标签列表标志
默认情况下,浏览器使用一个黑圆圈作为列表标志,可以用图片取代它: ul {list-style: none} ul li{ background-image: url("img/logo_0 ...
- PHP05 PHP语言基础
学习要点 初识PHP 基础语法 变量 常量 运算符 表达式 学习目标 掌握PHP基础语法 掌握PHP变量 掌握PHP常量 掌握PHP表达式 掌握PHP运算符 初识PHP 第一个PHP程序 编写代码 1 ...
- Report Builder 打开报错
提示:REP-0756:警告:找不到PL/SQL程序库’inv.pll’. 解决办法 处理:1.运行 ---输入REgedit ,在注册表内,查找注册表项Reports_path. 2.将下载的.pl ...
- 出现了错误。详细消息: 3 uncommitted changes would be overwritten by merge
merge manual中有一条警告: 出现了错误.详细消息: 3 uncommitted changes would be overwritten by merge 有未提交修改情况下,不要执行me ...
- Java开发中常见的异常问题
要调试程序,自然需要对程序中的常见的异常有一定的了解,因此在这里我将一些常见的Java程序中的异常列举出来给大家参考 AD: 作为一名开发者,Java程序员,很自然必须熟悉对程序的调试方法.而要调试程 ...
- PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)
PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++: 欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...
- Windows 命令收集
定时关机命令:schtasks /create /tn "关机" /tr "shutdown /s" /sc once /st 23:55
- 【转载】WampServer图标显示红色后变成橙色怎么解决
WampServer就是Windows Apache Mysql PHP集成安装环境,即在window下的apache.php和mysql的服务器软件. 工具/原料 WampServer 方法/步 ...