一、什么是面向对象

  • 面向过程:根据业务逻辑从上到下写垒代码
  • 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
  • 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

优点:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。

缺点:

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-面向对象的更多相关文章

  1. 初探C++Primer(15.面向对象程序设计)

    最近在恶补OOP相关知识,很遗憾学校的课没选上,于是只能上网购进C++Primer一本,开始重学C++之旅... (壮哉我大ZJU,网购半天到货XDD) 学习路线 7.类->13.类设计者的工具 ...

  2. python基础——面向对象编程

    python基础——面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的 ...

  3. Python的面向对象3

    接下来,我们接着讲Python的面向对象,在上一次的博客中,我们详细介绍了类与对象的属性,今天,我们来详细介绍一下面向对象中的方法! 1.定义实例方法 一个实例的私有属性就是以__开头的属性,无法被外 ...

  4. Python的面向对象2

    我们接着讲解Python的面向对象 1.初始化实例属性 在现实生活中,一种类型的实例会具有相同的某些属性,把这些实例划分为一个类型,则这些实例必然有相似的部分.但是,在创建实例之后,我们一个一个的为实 ...

  5. Python的面向对象1

    今天,我们来介绍Python的面向对象编程,其实面向对象并不陌生,在C++  ,Java  ,PHP中也有大量使用! 好了,我们来步入正题! 那什么是面向对象编程呢? 1. 面向对象编程是一种程序设计 ...

  6. My way to Python - Day05 - 面向对象-思维导图

    My way to Python - Day05 - 面向对象   思维导图

  7. Python进阶---面向对象的程序设计思想

    Python的面向对象 一.面向过程与面向对象的对比 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优 ...

  8. Python之面向对象一

    引子 小游戏:人狗大战 角色:人和狗 角色属性:姓名,血量,战斗力和性别(种类) 技能:打/咬 用函数实现人打狗和狗咬人的情形 def Dog(name,blood,aggr,kind): dog = ...

  9. python基础——面向对象进阶下

    python基础--面向对象进阶下 1 __setitem__,__getitem,__delitem__ 把对象操作属性模拟成字典的格式 想对比__getattr__(), __setattr__( ...

  10. python基础——面向对象进阶

    python基础--面向对象进阶 1.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 ...

随机推荐

  1. 实训作业6 (数据I/O)

    1. 文件输出流的应用. 定义如下字符串: String str = “12345abcdef@#%&*软件工程”; 编写程序将该字符串写入文件”data.txt”. import java. ...

  2. (尚020)Vue打包发布项目

    1.项目的打包与发布 1.1打包: npm run build 报错: 原因:原来eslint是一个语法检查工具,但是限制很严格,在我的vue文件里面很多空格都会导致红线(红线可以关闭提示),虽然可以 ...

  3. [RN] React Native 使用 react-navigation 报错 "Unable to resolve module `react-native-gesture-handler`

    在React Native 使用 react-navigation 过程中,报错 "Unable to resolve module `react-native-gesture-handle ...

  4. Processing设计Android APP(1) - 安装

    1.安装环境: A. Android Studio B. Processing 3.4 (64bit) 首先,直接安装Android Studio,我这里版本是3.2.1. 然后,新建一个Sample ...

  5. 平安银行Java面试-社招-五面(2019/09)

    个人情况 2017年毕业,普通本科,计算机科学与技术专业,毕业后在一个二三线小城市从事Java开发,2年Java开发经验.做过分布式开发,没有高并发的处理经验,平时做To G的项目居多.写下面经是希望 ...

  6. mysql avg()函数,获取字段的平均值

    mysql> select * from table1; +----------+------------+-----+---------------------+ | name_new | t ...

  7. Tkinter 之文件管理器

    一.效果图 二.功能描述 1.打开文件菜单中的打开按钮,可以选择目录. 2.可以查看各种类型的图片. 3.可以编辑文本. 4.显示行号功能,可改变目录显示的宽度. 三.使用的标签 1.Menu 2.F ...

  8. CTF SSRF(服务器端伪造请求)

    目录 CTF SSRF(服务器端伪造请求) 一.概念 二.危害 三.漏洞挖掘与判断 四.相关函数 五.IP绕过 六.Gopher协议 1.使用限制 2.构造payload CTF SSRF(服务器端伪 ...

  9. tensorflow运行时openssl与boringssl兼容性问题

    tensorflow中,grpc使用boringssl进行加密,boringssl是google基于openssl自行开发的一条分支,有许多相同函数,但底层实现以及支持的加密类型有不同. 且tenso ...

  10. GIS地理处理脚本案例教程——批量栅格分割-批量栅格裁剪-批量栅格掩膜-深度学习样本批量提取

    GIS地理处理脚本案例教程--批量栅格分割-批量栅格裁剪-批量栅格掩膜-深度学习样本批量提取 商务合作,科技咨询,版权转让:向日葵,135-4855_4328,xiexiaokui#qq.com 关键 ...