Python-15-面向对象
一、什么是面向对象
- 面向过程:根据业务逻辑从上到下写垒代码
- 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
- 面向对象:对函数进行分类和封装,让开发“更快更好更强...”
优点:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
缺点:
1. 编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题。一些扩展性要求低的场景使用面向对象会徒增编程难度,比如管理linux系统的shell脚本就不适合用面向对象去设计,面向过程反而更加适合。
2. 无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法准确地预测最终结果。于是我们经常看到对战类游戏,新增一个游戏人物,在对战的过程中极容易出现阴霸的技能,一刀砍死3个人,这种情况是无法准确预知的,只有对象之间交互才能准确地知道最终的结果。
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方
面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。
# 不是只有class才叫面向对象
def dog(name, gender):
def jiao():
print('一只狗[%s]正在叫' % name) def chi_shi():
print('一只[%s]正在吃屎' % name) def init():
dog1 = {
'name': name,
'gender': gender,
'type': type,
'jiao': jiao,
'chi_shi': chi_shi
}
return dog1 return init() res = dog('alex', 'male')
res['jiao']()
二、类与对象
类: 把一类事物相似的特征和动作整合到一起就是类,类是一个抽象概念
对象:基于类创建的具体事物(具体存在的)
在现实世界中:先有对象,再有类
世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,如人类、动物类、植物类等概念
也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在
在程序中:务必保证先定义类,后产生对象
这与函数的使用是类似的,先定义函数,后调用函数,类也是一样的,在程序中需要先定义类,后调用类
不一样的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象
# 经典类
class Stu:
pass
# 新式类
class Stu(object): # (object),表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
pass
class Student(object):
school = '123' # __init__方法是在对象产生之后才会执行,只用来为对象进行初始化操作,可以有任意python代码,但一定不能有返回值
def __init__(self, name, age):
self.name = name
self.age = age def learn(self):
print('is learning') def eat(self):
print('is eating') def sleep(self):
print('is sleeping') # #注意:
# 1.类中可以有任意python代码,这些代码在类定义阶段便会执行
# 2.因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过Student.__dict__查看
# 3.对于经典类来说我们可以通过该字典操作类名称空间的名字(新式类有限制),但python为我们提供专门的.语法
# 4.点是访问属性的语法,类中定义的名字,都是类的属性 # 程序中类的用法
print(Student.__dict__) # {'__module__': '__main__', 'school': '123', '__init__': <function Student.__init__ at 0x000001C3519D4488>,
# 'learn': <function Student.learn at 0x000001C3519D4510>, 'eat': <function Student.eat at 0x000001C3519D4598>,
# 'sleep': <function Student.sleep at 0x000001C3519D4620>, # '__dict__': <attribute '__dict__' of 'Student' objects>,
# '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
# .专门用来访问属性,本质操作的就是__dict__
# Student.school # 等于经典类的操作Student.__dict__['school']
# Student.school = 'Oldboy' # 等于经典类的操作Student.__dict__['school']='Oldboy'
# Student.x = 1 # 等于经典类的操作Student.__dict__['x']=1
# del Student.x # 等于经典类的操作Student.__dict__.pop('x') stu1 = Student('alex', 18) # 调用类,实例化得到对象
print(stu1.__dict__) # {'name': 'alex', 'age': 18}
print(stu1.name) # 相当于stu1.__dict__['name']
stu1.sleep()
使用isinstance检查obj是否是类 cls 的对象
class A(object):
pass
class B(object):
pass a = A()
print(isinstance(a, A))
print(isinstance(a, (A, B))) # 可以传入一个元组,只要元组内有一个符合就返回True
三、静态属性、类方法、静态方法
1. 静态属性
把一个函数属性变成数据属性,只需要使用@property就可以了。
class School(object):
def __init__(self, width, length):
self.width = width
self.length = length
def cal_area(self):
return self.width * self.length s = School(100, 100)
print(s.cal_area()) class School(object):
def __init__(self, width, length):
self.width = width
self.length = length
@property
def cal_area(self):
return self.width * self.length s = School(100, 100)
print(s.cal_area)
2. 类方法
类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量。
# 访问实例变量
class Person(object):
def __init__(self, name, country):
self.name = name
self.country = country
@classmethod
def nationality(self):
print('Bigberg is %s.' % self.country) p = Person('Bigberg', 'CN')
p.nationality() # 输出
Traceback (most recent call last):
File "G:/python/untitled/study6/静态方法.py", line 31, in <module>
p.nationality()
File "G:/python/untitled/study6/静态方法.py", line 24, in nationality
print('Bigberg is %s.' % self.country)
AttributeError: type object 'Person' has no attribute 'country' # 访问类变量
class Person(object):
country = 'Chinese' # 增加一个 全局属性/静态字段
def __init__(self, name, country):
self.name = name
self.country = country
@classmethod
def nationality(cls): # 这里将sefl 改为 cls
print('Bigberg is %s.' % cls.country) p = Person('Bigberg', 'CN')
p.nationality() # 输出
Bigberg is Chinese.
class Person(object): def __init__(self, name, country):
self.name = name
self.country = country
def nationality(self):
print('Bigberg is %s.' % self.country) Person.nationality(Person) # 需要一个参数 class Person(object):
country = 'Chinese' # 增加一个 全局属性/静态字段
def __init__(self, name, country):
self.name = name
self.country = country
@classmethod
def nationality(cls): # 这里将sefl 改为 cls
print('Bigberg is %s.' % cls.country) Person.nationality() # 不需要参数
3. 静态方法
在类中的方法前面通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法
普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法。
class Person(object): def __init__(self, name):
self.name = name @staticmethod
def speak():
print('someone is speaking chinese.') # 静态方法在类中也不需要传入 self参数
静态方法是不能访问实例变量和类变量的
class Person(object):
def __init__(self, name):
self.name = name
@staticmethod
def speak(self):
print('%s is speaking chinese.' % self.name) p = Person('Bigberg')
p.speak() # 我们在 speak(self) 函数中传入 self
# 事实上以上代码运行会出错的,说speak 需要一个self参数,但调用时却没有传递,没错,当speak变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。
Traceback (most recent call last):
File "G:/python/untitled/study6/静态方法.py", line 26, in <module>
p.speak()
TypeError: speak() missing 1 required positional argument: 'self'
想让以上代码可以正常执行,有两种方法:
- 在调用时将实例本身传给 speak()
class Person(object):
def __init__(self, name):
self.name = name
@staticmethod
def speak(self):
print('%s is speaking chinese.' % self.name) p = Person('Bigberg')
p.speak(p) # 输出
Bigberg is speaking chinese.
- 在方法speak中去掉self,但这也意味着,不能通过self.调用实例中的其它变量了
class Person(object):
def __init__(self, name):
self.name = name
@staticmethod
def speak(): # 方法中已经没有 self 参数了
print('%s is speaking chinese.' % 'anyone') p = Person('Bigberg')
p.speak() #输出
anyone is speaking chinese.
Python-15-面向对象的更多相关文章
- 初探C++Primer(15.面向对象程序设计)
最近在恶补OOP相关知识,很遗憾学校的课没选上,于是只能上网购进C++Primer一本,开始重学C++之旅... (壮哉我大ZJU,网购半天到货XDD) 学习路线 7.类->13.类设计者的工具 ...
- python基础——面向对象编程
python基础——面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的 ...
- Python的面向对象3
接下来,我们接着讲Python的面向对象,在上一次的博客中,我们详细介绍了类与对象的属性,今天,我们来详细介绍一下面向对象中的方法! 1.定义实例方法 一个实例的私有属性就是以__开头的属性,无法被外 ...
- Python的面向对象2
我们接着讲解Python的面向对象 1.初始化实例属性 在现实生活中,一种类型的实例会具有相同的某些属性,把这些实例划分为一个类型,则这些实例必然有相似的部分.但是,在创建实例之后,我们一个一个的为实 ...
- Python的面向对象1
今天,我们来介绍Python的面向对象编程,其实面向对象并不陌生,在C++ ,Java ,PHP中也有大量使用! 好了,我们来步入正题! 那什么是面向对象编程呢? 1. 面向对象编程是一种程序设计 ...
- My way to Python - Day05 - 面向对象-思维导图
My way to Python - Day05 - 面向对象 思维导图
- Python进阶---面向对象的程序设计思想
Python的面向对象 一.面向过程与面向对象的对比 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优 ...
- Python之面向对象一
引子 小游戏:人狗大战 角色:人和狗 角色属性:姓名,血量,战斗力和性别(种类) 技能:打/咬 用函数实现人打狗和狗咬人的情形 def Dog(name,blood,aggr,kind): dog = ...
- python基础——面向对象进阶下
python基础--面向对象进阶下 1 __setitem__,__getitem,__delitem__ 把对象操作属性模拟成字典的格式 想对比__getattr__(), __setattr__( ...
- python基础——面向对象进阶
python基础--面向对象进阶 1.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 ...
随机推荐
- AJax和JQ的结合使用
第一种经典模式 <%-- Created by IntelliJ IDEA. User: 60590 Date: 2019/12/4 Time: 16:08 To change this tem ...
- HBASE-LSM树(转载)
HBASE-LSM树 1.B+树 关于B树.B+树.B树的了解参考:* http://blog.csdn.net/v_july_v/article/details/6530142 优点: 走进搜索引擎 ...
- php之大文件分段上传、断点续传
前段时间做视频上传业务,通过网页上传视频到服务器. 视频大小 小则几十M,大则 1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制:2,请求时间过长, ...
- hibernate实现增删改查
1.需要先创建学生实体: package pers.zhb.domain; public class Student { private int studentno; private String s ...
- Building a Service Mesh with HAProxy and Consul
转自:https://www.haproxy.com/blog/building-a-service-mesh-with-haproxy-and-consul/ HashiCorp added a s ...
- 移动端tap事件(轻击、轻触)
一.问题 ①移动端也有click点击事件,click点击会延迟200~300ms ②因为点击的响应过慢,影响了用户体验,所以需要解决响应慢的问题 二.解决方案 ①使用tap事件:即轻击,轻敲,响应速度 ...
- vscode 添加eslint插件
1. 安装vscode中的eslint插件 Ctrl + Shift + P 调出控制台,输入install,再在插件版块查找ESLint,安装 2. 安装node,安装npm 3. 全局安装ESLi ...
- Cocos CreatorUI系统上
若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理. 请点赞!因为你们的赞同/鼓励是我写作的最大动力! 欢迎关注达叔小生的简书! 这是一个有质量 ...
- 转载:理解scala中的Symbol
相信很多人和我一样,在刚接触Scala时,会觉得Symbol类型很奇怪,既然Scala中字符串都是不可变的,那么Symbol类型到底有什么作用呢? 简单来说,相比较于String类型,Symbol类型 ...
- mapreduce中reduce没有执行
hadoop执行mapreduce过程reduce不执行原因 1.如果你的map过程中没有context.write()是不执行reduce过程的:2.如果你的map过程中context.write( ...