55555555555555

在这里插入图片描述

欢迎关注博主 Mindtechnist 或加入【Linux C/C++/Python社区】一起学习和分享Linux、C、C++、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。


python面向对象 | 类和对象

    • 三大编程范式
    • 类的属性
    • 类和实例对象
    • 对象和实例属性
    • 类和实例的作用域
    • 静态与组合
      • 静态属性
      • 类方法
      • 静态方法
      • 组合


专栏:《python从入门到实战》


三大编程范式

三大编程范式是指:面向过程编程、函数式编程和面向对象编程。三种编程范式只是习惯不同,但是并没有高低之分。正如那句话所说,天下武功门派没有高低之分,只有习武之人的高低之分。
我们都知道C语言是面向过程的,C++是面向对象的。但是,并不是说C语言一定就只能面向过程,我们用C也可以实现面向对象(实际上在Linux内核中就有很多面向对象的思想),而C++也可以面向过程编程,只能说C++提供了一些特性可以更好地支持面向对象。总之,三大编程范式没有高低之分,也没有和具体的语言绑定这一说。
需要注意的是,函数式编程 ≠ 用函数编程 ,函数式编程就是用python内的函数来表达出数学层面的函数,二者结合就是函数式编程,即数学函数+python函数
编程最开始是无组织无结构的,从简单的控制流中按步骤写指令,从指令中提取出重复的代码块或逻辑,组织到一起,便实现了代码复用,这也标志着代码由无结构走向了结构化,写程序的过程也具有了逻辑性。如果我们定义函数,并在函数外定义变量,将变量以参数的形式传递给函数,这就实现了数据与动作的分离,如果更进一步,我们把数据和动作内嵌到一个结构里面,那我们就有了一个对象系统。也就是说,对象是数据和函数的结合物。
注意:类和对象是有区别的,类是抽象的概念,抽象出共同属性和方法,对象是一个实例,是类实例化出来的对象。面向对象编程并不等于面向类编程,函数和类都可以实现面向对象编程。
下面是一个用函数实现面向对象的例子

def city(name, addr, type):
    def init(name, addr, type):
        c = {
            'name':name,
            'addr':addr,
            'type':type,
            'visit':visit,
        }
        return c

    def visit(c):
        print('%s %s %s 欢迎您' %(c['addr'], c['type'], c['name']))

    return init(name, addr, type)

c1 = city('济南', '山东', '省会')

类的属性

声明一个类和声明一个函数很相似,我们使用函数实现面向对象程序设计的时候,是通过返回值得到具体对象的,同样class()也表示执行这个类,也是实例化的过程,和函数一样,它会返回一个对象。
注意:python2分为经典类和新式类,python3统一都是新式类。

class c1:
	‘经典类’
	pass
class c2(parent_class):
	‘新式类’
	pass

类的属性有两种,数据属性和函数属性。
数据属性:变量(实例对象只有数据属性)。
函数属性:方法,即函数。

print(classname) #打印类的属性 – 属性名列表
print(classname.__dict__) #查看类的属性字典 – 属性的键值对
print(classname.__dict__[‘attrname’]) #获取某一个属性
classname.__dict__[‘funcname’]() #运行类的某一个属方法

python为类内置的特殊属性

类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类 – python中所有类都有一个共同父类
类名.__bases__# 类所有父类构成的元组
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)

类和实例对象

类的作用域和函数一样,调用类的属性时,会先在自己作用域寻找,自己作用域找不到再去上一层作用域寻找。
实例只有数据属性,但是实例对象可以调用类的数据属性。
实际上,实例就是用通过类的__init__产生的,它只包含__init__方法内的一些属性。
实例没有方法属性,但是实例可以调用类的方法属性,注意调用的方法是类的,而不是实例自己的。
如果想调用类的方法,需要通过类去调用(实例对象无法调用类的方法,因为不在作用域内),并把实例作为参数传给classname.function(obj)。
类中的方法,一般都要设置一个参数self,当使用实例调用类的方法时,默认会把实例对象本身传给self。实例调用方法会自动传参self,但是类调用方法需要手动传入实例参数。
实例是由类中的__init__方法产生的,由__init__传参并返回的对象,实力只含有__init__内的数据属性,但是实例可以访问类的数据属性(__init__外部的),因为实例的作用域也就是__init__的作用域在类的作用域之内,(可以访问上一层作用域的变量),但是实例是没有方法属性的,实例想调用方法只能去找类要,并把自己传过去。(类中的方法都有一个默认参数,在第一个位置,也就是self,它用于指向实例自己)。
可以对类的数据属性和方法属性进行增删改查;
对实例的数据属性也可以增删改查,也可以对实例增加方法属性,调用的时候相当于调用实例自己的方法,需要手动把实例自己(不传自己也行,实际上传啥都可以)传进去赋给self(实例调用类的方法时是自动传参给self的,传的是自己)。- 但是不要给实例增加方法,应该把实例的数据属性和方法分离,同一个类创建的实例调用的都是类的方法,这样数据和方法就分离了。

对象和实例属性

实际上,实例化就是类名()的过程,其返回结果是一个对象,加上括号的行为和函数的运行非常相似。类和函数一样有作用域,我们可以把类看作是最外层的函数,也就是最大的作用域。实例化会自动触发init函数的运行,最后返回一个值,也就是实例,我们需要的实例属性就存放在init函数的局部作用域里。类有类的属性字典,即类的作用域,而实例有实例的属性字典,即实例的作用域。也就是说,当我们使用对象的方法时obj.func()会先在自己的作用域找,找不到再去外层类的字典中去找,都找不到才会报错。

类和实例的作用域

#---------------------------------------------------------
class People:
	name = ‘su’
	def __init__(self, age): #通过自动运行__init__进行实例化
    	self.age = age #实例的作用域在__init__内
	def test(self, string)
    	print(‘test %s’ %string)

p1 = People(18)
p1.name = ‘yy’ 
#相当于在实例的字典中增加一个属性,和类的字典毫无关系
print(People.name) # su
print(p1.name) #yy

#---------------------------------------------------------

name = ‘su’
class People:
	def __init__(self, age): 
    	self.age = age 
	def test(self, string)
    	print(‘test %s’ %string)
p1 = People(18)
print(p1.name) #err – 只会在类的作用域内部找

#---------------------------------------------------------

class People:
	def __init__(self): #__init__除了不能返回值,和普通函数无区别
    	age = input(input age’) 
    	self.age = age 
	def test(self, string)
    	print(‘test %s’ %string)
#千万不要这样做

#---------------------------------------------------------

name = ‘su’
class People:
	def __init__(self, age): 
    	self.age = age 
    	print(‘name: --, name) #可以打印出
	def test(self, string)
    	print(‘test %s’ %string)
p1 = People(18)
#只有以点.去访问的时候,才遵循在类的内部去找的原则,因为.是成员运算符

#---------------------------------------------------------

name = ‘su’
class People:
    name = ‘tt’
	def __init__(self, age): 
    	self.age = age 
    	print(‘name: --, name) #su
	def test(self, string)
    	print(‘test %s’ %string)
p1 = People(18)
print(People.name)
print(p1.name)
# .调用方式在类内部寻找,遵循类的作用域,在类和实例的字典中去找
#不用.访问,那么就和类还有实例没关系,就是访问普通变量,它就不会在类还有实例的字典内找变量,而是查找普通变量

#---------------------------------------------------------

class People:
	name = ‘tt’
	l = [‘a’, ‘b’]
	def __init__(self, age): 
    	self.age = age 
	def test(self, string)
    	print(‘test %s’ %string)
p1 = People(18)
print(p1, l)
p1.l = [1, 2, 3] #改的是实例,在实例的字典中加了一个列表
#给实例新增加了一个新属性,= 表示新增
print(People.l)
print(p1.l)
p1.l.append(‘c’) #这里没有用等号,所以不会给实例p1增加新属性
#这就是改的类的属性了
print(p1.__dict__) #实例的属性字典
print(People__dict__) #类的属性字典

静态与组合

静态属性

@property - 装饰器

class People:
	def __init__(self, name, age): 
    	self.name = name 
	self.age = age
	@property 
	def get_attr(self):
    	#print(‘%s - %s’ %( self.name, self.age))
    	return [name, age]
p1 = People(‘su’, 17)
p1.get_attr  #调用的时候不再加()就可以执行
#调用方法属性和调用数据属性一样,这样就隐藏了背后的实现逻辑
#调用者调用的时候,只能看到结果,但是无法得知背后的逻辑实现
#把方法属性封装起来像数据属性一样

类方法

@classmethod

class People:
    tag = 1
	def __init__(self, name, age): 
    	self.name = name 
		self.age = age
	@property 
	def get_attr(self):
    	#print(‘%s - %s’ %(self.name, self.age))
    	return [name, age]
	def get_tag(self):
    	print(%s’ %self.tag)
People.get_tag(x) #原则上可以传入任何参数,但是底层self.tag限制了必须传入一个实例
p1 = People(‘su’, 17)
People.get_tag(p1)
#我的需求是,只打印类的方法,我不想和实例捆绑在一块
class People:
    tag = 1
	def __init__(self, name, age): 
    	self.name = name 
		self.age = age
	@property 
	def get_attr(self):
    	#print(‘%s - %s’ %(self.name, self.age))
    	return [name, age]
	@classmethod
	def get_tag(cls): #参数是一个类名
    	print(%s’ %cls.tag)
People.get_tag() #将类和实例分离 – 提供了由类调用的方法 – 类方法
#类方法也会自动传参,会把调用的类名自动传入给cls
#类方法只能调用类属性,不能调用实例属性,实例属性是由self调用的
#只要参数带self,那么这个方法就和实例绑定了
#cls就是和类绑定
#实例也能调用类方法 – 但是最好不要这样做,类方法出现的意义就是给类调用

静态方法

@staticmethod

class People:
	def __init__(self, name, age): 
    	self.name = name 
		self.age = age
	@property 
	def get_attr(self):
    	print(%s - %s’ %(self.name, self.age))
	@staticmethod #类的工具包
	def do_thing(a, b, c):
    	print(a, b, c)
	def do_thing2(a, b, c):
    	print(a, b, c)

print(People.__dict__)
p1 = People(‘su’, 17)
print(p1.__dict__)
People.do_thing(1, 2, 3) #ok – 不会自动传参
p1.do_thing(1, 2, 3) #ok – 不会自动传参
People.do_thing2(1, 2, 3) #ok
p1.do_thing2(1, 2, 3) #error #p1会自动把自己传进去 – 参数错误

#  @property – 将方法和实例绑定 – 用self调用实例属性 – 自动传入实例本身给self
#  @classmethod – 将方法和类绑定(和实例就没关系了)- 用cls调用类的属性 – 自动传入本身给cls
#  @staticmethod – 既不和实例绑定也不和类绑定,和实例和类都没关系了,是一个类的工具包 – 不会自动传参
# 静态方法staticmethod只是名义上归属类管理,不能使用类变量和实例变量,是类的工具包 – 既没有self也没有cls,无法通过.去调用属性

组合

组合是做关联的,类与类之间没有共同点,但是它们之间是有关联的,这时就用组合去解决,去建立关联。(实例对象做参数,类做参数)
在这里插入图片描述
这里面的Head()、Foot()等就是一个对象,类名加()本身就是实例化的意思,所以上面的效果和直接传递一个实例对象的参数效果是一致的。


在这里插入图片描述
在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/517579.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QoS特性详解

​什么是QOS QoS(Quality of Service)是服务质量的简称,是指网络向特定流量提供特定的服务的能力。QoS可以确保关键业务的流畅运行,提高网络资源利用率,并保障网络安全。 常见网络设备QoS特性: 思科交换机: 支持基于策略的QoS(PBR)和基于类的QoS(CBQoS)。 PBR: 基于源I…

ubuntu更换国内镜像源,下载增速

方法一:通过脚本更换源 1.备份原来的源 sudo cp /etc/apt/sources.list /etc/apt/sources_init.list 将原来的源保留一下,以后想用还可以继续用 2.更换源 sudo gedit /etc/apt/sources.list 使用gedit打开文档,将下面的阿里源复制进去&am…

每日五道java面试题之ZooKeeper篇(一)

目录: 第一题. ZooKeeper 是什么?第二题. Zookeeper 文件系统第三题. Zookeeper 怎么保证主从节点的状态同步?第四题. 四种类型的数据节点 Znode第五题 . Zookeeper Watcher 机制 – 数据变更通知 第一题. ZooKeeper 是什么? Zoo…

「精细化管理」某物业集团精细化管理咨询项目纪实

实现工作例行化、定时化、程序化与可视化企业重视绩效考核,却总感觉考核不到点上;企业重视规划职责,却总感觉部门间职责不清;企业重视激励,却总感觉难以真正激励员工。到底是哪里出了问题?华恒智信指出&…

mbti,ESTP型人格的心理问题分析

什么是ESTP型人格 ESTP分别代表外向,实感,理智,依赖,而ESTP型人格则是一种性格上十分激进,喜欢冒险,并且总是因为情绪起伏过大,而一下子做出应激行为的相对冒险的人格。具有ESTP型人格的人一般…

一文掌握线程池实现原理

线程池简介 Java在使用线程执行程序时,需要调用操作系统内核的API创建一个内核线程,操作系统要为线程分配一系列的资源;当该Java线程被终止时,对应的内核线程也会被回收。因此,频繁的创建和销毁线程需要消耗大量资源。…

开源模型应用落地-chatglm3-6b模型小试-入门篇(三)

一、前言 刚开始接触AI时,您可能会感到困惑,因为面对众多开源模型的选择,不知道应该选择哪个模型,也不知道如何调用最基本的模型。但是不用担心,我将陪伴您一起逐步入门,解决这些问题。 在信息时代&#xf…

单例模式以及线程安全问题

单例模式的概念 单例模式是指的是整个系统生命周期内,保证一个类只能产生一个实例对象 保证类的唯一性 。 通过一些编码上的技巧,使编译器可以自动发现咱们的代码中是否有多个实例,并且在尝试创建多个实例的时候,直接编译出错。 …

【Qt 学习笔记】使用两种方式实现helloworld

博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 使用两种方式实现helloworld 文章编号:Qt 学习笔记 / 05 …

不同路径- java

题目描述: 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径&#xff…

页面刚加载的时候显示自己定义的{{***}}然后一闪而过

这时候别用插值表达式语法了,直接用v-text或者v-html就能解决这个问题 但是有个问题,如下图所示: 具体bind使用方式,如下图所示: 但是v-bind也可以进行简写,就是去掉v-bind,直接写&#xff1a…

提高空调压缩机能效的通用方法

压缩机的能效提高主要依靠技术改进而不是大幅度增加材料的消耗,这也是技术经济性最好的节能手段。 1、改进电机效率,电机效率的提高意味着压缩机电效率的提高和压缩机总体效率的提高; 1.1、降低定子铜耗 降低定子绕组中电流通过所产生的铜耗…

Java零基础入门-java8新特性(完结篇)

一、概述 ​上几期,我们是完整的学完了java异常类的学习及实战演示、以及学习了线程进程等基础概念,而这一期,我们要来玩点好的东西,那就是java8,我们都知道java8是自2004年发布java5之后最重要且一次重大的版本更新&a…

【通信原理笔记】【三】模拟信号调制——3.2 双边带抑制载波调制(DSB-SC)

文章目录 前言一、DSB-SC的数学表示二、DSB-SC的相干解调三、DSB-SC的性能评价总结 前言 从这一篇开始我们依次介绍几种模拟信号调制的方法,包括其数学表达式,系统框图、解调方式、性能评价等。 一、DSB-SC的数学表示 将 m ( t ) m(t) m(t)作为已调信号…

《机器学习算法面试宝典》正式发布!

大家好,历时半年的梳理和修改,《机器学习算法面试宝典》(以下简称《算法面试宝典》)终于可以跟大家见面了。 近年来,很多理科专业学生也纷纷转入算法赛道,特别是最近 ChatGPT 的爆火,推动了AI …

单片机之LED与按键

目录 LED LED灯亮的原理图 LED灯光闪烁 电路设计 keil文件 LED流水灯的实现 keil文件 单片机之按键 键盘的结构 按键消抖 软件消抖 硬件消抖 键盘的分类 独立式键盘 行列式键盘 键盘的识别 独立按键案例 电路图 keil文件 行列式键盘案例 电路图 对应按键…

蓝桥杯:七步诗 ← bfs

【题目来源】https://www.lanqiao.cn/problems/3447/learning/【题目描述】 煮豆燃豆苴,豆在釜中泣。本是同根生,相煎何太急?---曹植 所以,这道题目关乎豆子! 话说赤壁之战结束后,曹操的船舰被刘备烧了,引领军队从华容…

PAC性能开销权衡及优化措施

PAC性能开销?如何进行优化?本博客探讨这些问题。

11.python的字典dict(下) 遍历字典,结构优化

11.python的字典dict(下) 遍历所有的键值对 items()方法是字典的一个内置方法,用于返回字典中所有键值对的视图(view)。它返回一个可迭代的对象,每个元素都是一个包含键和对应值的元组。 下面用一个例子来说明items()方法的用法…

蓝桥杯单片机速成8-NE555频率测量

一、原理图 NOTE:使用NE555测量频率之前,需要将J3-15(SIGNAL)与J3-16(P34短接) 在使用矩阵键盘的时候也记得把跳冒拔下,因为有公共引脚P34 又是因为他的输出引脚是P34,所以只能用定时器0来作为计数器进行频率测量了 二、代码实现 …