test4122

在这里插入图片描述

欢迎关注博主 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 cdef 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) #sudef 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 = 1def __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 = 1def __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]@classmethoddef 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()等就是一个对象,类名加()本身就是实例化的意思,所以上面的效果和直接传递一个实例对象的参数效果是一致的。


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


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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Shenandoah GC算法

概述 最早由Red Hat公司发起,目标是利用现代多核CPU的优势,减少大堆内存在GC时产生的停顿时间。随OpenJDK 12一起发布,暂停时间不依赖于堆的大小;这意味着无论堆的大小如何,暂停时间都是差不多的。 Shenandoah最初的…

Multisim仿真二极管、晶体管和场效应管学习笔记

Multisim仿真二极管、晶体管和场效应管 (note:使用Multisim14.0版本进行仿真) 文章目录 Multisim仿真二极管、晶体管和场效应管二极管的I-V特性晶体管的I-V特性场效应管的I-V特性 二极管的I-V特性 插入I-V analyzer 原理图绘制 改变仿真…

【Python】Python城乡人口数据分析可视化(代码+数据集)【独一无二】

👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…

c# .net 香橙派 Orangepi GPIO高低电平、上升沿触发\下降沿触发 监听回调方法

c# .net 香橙派GPIO高低电平、上升沿触发\下降沿触发 监听回调方法 通过gpio readall 查看 gpio编码 这里用orangepi zero3 ,gpio= 70为例 当gpio 70 输入高电平时,触发回调 c# .net 代码 方法1: Nuget 包 System.Device.Gpio ,微软官方库对香橙派支持越来越好了,用得…

日程安排组件DHTMLX Scheduler v7.0新版亮点 - 拥有多种全新的主题

DHTMLX Scheduler是一个类似于Google日历的JavaScript日程安排控件,日历事件通过Ajax动态加载,支持通过拖放功能调整事件日期和时间,事件可以按天、周、月三个种视图显示。 备受关注的DHTMLX Scheduler 7.0版本日前正式发布了,如…

为什么你选择成为一名程序员?

逐码探梦:我选择程序员之路 在数字化的纹理中编织梦想,于逻辑的海洋里追寻真理,程序员,这个职业对我而言不仅仅是一份工作,更是一扇通向无限可能性的大门。选择成为一名程序员,是一个交织着兴趣和职业规划…

Python中sort()函数、sorted()函数的用法深入讲解(具体实例:蓝桥杯数位排序)

前置知识: 可迭代对象的定义:可迭代对象是指可以被迭代或遍历的对象,即可以使用循环结构对其进行逐个访问的对象。 在Python中常见的可迭代对象有:列表(list)、元组(tuple)、字符串(sting&…

微信小程序 django+nodejs电影院票务售票选座系统324kd

小程序Android端运行软件 微信开发者工具/hbuiderx uni-app框架:使用Vue.js开发跨平台应用的前端框架,编写一套代码,可编译到Android、小程序等平台。 前端:HTML5,CSS3 VUE 后端:java(springbootssm)/python(flaskdja…

Django框架的基础知识

Django(英文发音:dʒŋgəʊ)是一个开放源代码的Web应用框架,使用高性能的Python语言编写而成。Django框架的诞生,最初是用来开发和管理Lawrence Publishing Group(劳伦斯出版集团)旗下的新闻网…

【Mysql高可用集群-双主双活-myql+keeplived】

Mysql高可用集群-双主双活-myqlkeeplived 一、介绍二、准备工作1.两台centos7 linux服务器2.mysql安装包3.keepalived安装包 三、安装mysql1.在128、129两台服务器根据《linux安装mysql服务-两种安装方式教程》按方式一安装好mysql应用。2.修改128服务器/etc/my.cnf配置文件&am…

(非技术) 基因遗传相关知识学习笔记

目录 一、基因遗传名词解释 二、什么叫显性遗传和隐性遗传? 三、如何确定遗传性质呢?是显性还是隐性? 四、常规例子1: 五、常规例子2: 六、实际案例: 七、思考题: 八、参考: …

分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进麻雀优化算法优化最小二乘支持向量机分类预测

分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进麻雀优化算法优化最小二乘支持向量机分类预测 目录 分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进麻雀优化算法优化最小二乘支持向量机分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述…