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 的对象 ...
随机推荐
- 微信小程序路由带参
通过url带参传递 wxml <navigator url="../user/user?id={{item.id}}&name={{item.name}}">点 ...
- learning java 重定向标准输入输出
output redirectionOut: public class RedirectOut { public static void main(String[] args) throws File ...
- SQL必知必会收集学习
1.按查询列位置排序:如按第一列 降序排序 desc
- mysql开放远程连接
1.检查端口是否被监听,没有的话请启动mysql. netstat -atnp | grep 3306 2.检查用户是否具备远程连接,即host字段值不是 % mysql -uroot -p你的密码 ...
- mysql 设置字段是否可以为null
//不允许为null alter table table1 change id id ) not null; //允许为null alter table table1 change id id ) n ...
- Hadoop 在启动或者停止的时候需要输入yes确认问题
启动或者停止hadoop的时候,信息如下: Stopping namenodes on [hadoop1 hadoop2] The authenticity of host 'hadoop2 (172 ...
- mysql下sql语句令某字段值等于原值加上一个字符串
MYSQL在一个字段值后面加字符串,如下: member 表名 card 字段名 update member SET card = '00' || card; (postgreSQL 用 || 来连贯 ...
- HTTP/1.0和HTTP/1.1 http2.0的区别,HTTP怎么处理长连接(阿里)
HTTP1.0 HTTP 1.1主要区别 长连接 HTTP 1.0需要使用keep-alive参数来告知服务器端要建立一个长连接,而HTTP1.1默认支持长连接. HTTP是基于TCP/IP协议的,创 ...
- Dependency Parsing
句子的依赖结构表现在哪些单词依赖哪些单词.单词之间的这种关系及可以表示为优先级之间的关系等. Dependency Parsing 通常情况下,对于一个输入句子:\(S=w_{0} w_{1} \do ...
- egg.js搭建 api设置跨域
1.egg简述 Egg.js,为企业级框架和应用而生,是阿里开源的企业级 Node.js 框架. 2.特点 Egg 奉行『约定优于配置』,按照一套统一的约定进行应用开发,团队内部采用这种方式可以减少开 ...