Python面向对象设计和面向对象编程解析

简介: 我们都知道Python是一门灵活度很高的语言,它可以面向过程,面向对象,那我们今天说说Python中的面向对象设计和面向对象编程的区别面向对象设计和面向对象编程都提到了“面向对象”, 那么首先我们要搞清楚什么是对象对象:我们可以简单的理解为我们见到的每个实际存在的事物就是一个对象,如果一个人,一座房子,一只小猫等。

我们都知道Python是一门灵活度很高的语言,它可以面向过程,面向对象,那我们今天说说Python中的面向对象设计和面向对象编程的区别

面向对象设计和面向对象编程都提到了“面向对象”, 那么首先我们要搞清楚什么是对象

对象:我们可以简单的理解为我们见到的每个实际存在的事物就是一个对象,如果一个人,一座房子,一只小猫等。

那么我们想想,我们怎么面向对象,那就是以对象为中心,去描述这个对象,这个对象有什么特点,什么属性,什么功能等,想想假如你要去向别人描述一个丢失的小猫(一个对象),你要怎么描述呢?小够的品种,大小,毛色,等等。 当你把着一些特征或者属性描述清楚之后,一个对象就被定义下来了。

知道对象的概念之后,我们进入主题

1.面向对象设计

说到设计,我们可以理解为是一种想法,思路,就是把对象的属性,功能(python里用函数表达)糅合在一起形成一个对象,这种思想可以简单的理解为面向对象设计,不是说必须用CLASS这种,才叫面向对象设计,下面我们举个例子

def cat(name,gender,type):
    # 猫的的动作或者叫功能
    def cry(cat):
        print('一条小猫[%s],喵喵' % cat['name'])
    def run(cat):
        print('一条[%s]小猫正在跑' % cat['type'])
    def init(name,gender,type):
        cat = {
            'name':name,
            'gender': gender,
            'type': type,
            'cry':cry,
            'run':run,
        }
        return cat
    return init(name,gender,type)

cat=cat('毛球','公','波斯猫')
print(cat)
cat['cry'](cat)

结果

{'name': '毛球', 'gender': '公', 'type': '波斯猫', 'cry': <function cat.<locals>.cry at 0x0000022C6C9B71E0>, 'run': <function cat.<locals>.run at 0x0000022C6C9B7158>}
一条小猫[毛球],喵喵

上面我们用纯函数的方式去描述了一只小猫,但是我们也可以把上面这张方式理解为面向对象设计,因为上面我们把猫的属性和功能函数结合在一起,形式了一个对象。

我们用

cat=cat('毛球','公','波斯猫')

来生成一个对象,我们可以调用对象的属性和函数等等,这些都是我们熟悉的面向对象设计,但是我们不能说这种方式叫面向对象编程。

2.面向对象编程,

这个在很多语言中都在大量使用,简单的说使用Class来描述对象的方式就是面向对象编程。Python中当然也可以使用面向对象编程,但是不强求,如JAVA之类的编程语言就强制要求使用面向对象编程,个人认为不太友好。下面我们把上面的例子改成面向对象编程的方式来看看

class Cat:
    def __init__(self,name,gender,type):
        self.name = name
        self.gender = gender
        self.type = type

    def cry(self):
        print('一条小猫[%s],喵喵' % self.name)
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

cat =  Cat('毛球','公','波斯猫')
print(Cat)
cat.cry()

上面我们改成了个class的方式来编程,可以说就是使用面向对象编程的方式。也是我们熟悉的类方式。

3.面向对象编程的基础知识点拨

3.1类和函数的属性分类

类属性包含:数据属性和函数属性

对象属性包括:数据属性,对象如果向调用函数属性,其实是调用的类的函数属性

类的数据属性是所有对象共享的

类的函数属性是绑定给对象用的

怎么理解呢?我们可以使用__dict__方法来看属性

class Cat:
    weight = 5; #新定义了一个类的数据属性
    def __init__(self,name,gender,type): #实例属性
        self.name = name
        self.gender = gender
        self.type = type

    def cry(self): #类的函数属性
        print('一条小猫[%s],喵喵' % self.name)
    def run(self):  #类的函数属性
        print('一条[%s]小猫正在跑' % self.type)

cat =  Cat('毛球','公','波斯猫')
print(Cat.__dict__)
print(cat.__dict__)

结果

{'__module__': '__main__', 'weight': 5, '__init__': <function Cat.__init__ at 0x0000021E5DC671E0>, 'cry': <function Cat.cry at 0x0000021E5DC67158>, 'run': <function Cat.run at 0x0000021E5DC67268>, '__dict__': <attribute '__dict__' of 'Cat' objects>, '__weakref__': <attribute '__weakref__' of 'Cat' objects>, '__doc__': None}


{'name': '毛球', 'gender': '公', 'type': '波斯猫'}

上面一行是类的属性,我们可以看到我们定义的weight,'cry','run'等类的数据和函数属性

下面一行是对象的属性,只有init里面定义的数据属性,没有函数属性

当函数想调用方法时,是先从自己的属性里面找,如果没有就去上层类的__dict__里面去寻找,执行,所以我们说对象执行方法其实执行的是类的函数属性。

我们看到上面__dict__里面还有一些其他自带属性解释如下

#python为类内置的特殊属性
类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类(在讲继承时会讲)
类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)

3.2 self到底什么意思,什么时候使用

self我们可以理解为实例对象自己,那为什么在面向对象编程的时候,类的每个函数都要在第一个参数放self呢? 我的理解一方面是面向对象编程的语法需要,二深层次的说是把类的数据属性和函数属性糅合在一起,满足面向对象设计的思想

self在对象实例化的时候,会自动传入,如果函数属性里面不定义self会报错

class Cat:
    weight = 5;
    def __init__(self,name,gender,type):
        self.name = name
        self.gender = gender
        self.type = type

    def cry(): #没有写self
        print('一条小猫喵喵')
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

cat =  Cat('毛球','公','波斯猫')
cat.cry() #对象调用类的函数属性时候,会自己传入self也就是实例自己,作为第一个参数

结果报错

Traceback (most recent call last):
File "C:/Users/aryin/Desktop/mysite2/面向对象.py", line 14, in

cat.cry()

TypeError: cry() takes 0 positional arguments but 1 was given

仔细看报错,cry() takes 0 positional arguments but 1 was given,说我们给它传了一个参数,但是上面的代码里,我们什么也没传,所以这是python自己给我们默认传了一个self参数

那我们看看我们直接用类自己来调用它的函数属性,看看会不会自己传入self参数

class Cat:
    weight = 5;
    def __init__(self,name,gender,type):
        self.name = name
        self.gender = gender
        self.type = type

    def cry(self): #没有写self
        print('一条小猫喵喵')
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

cat =  Cat('毛球','公','波斯猫')
Cat.cry() #类调用自己的函数属性,不传入参数

结果报错

Traceback (most recent call last):
File "C:/Users/aryin/Desktop/mysite2/面向对象.py", line 15, in

Cat.cry()

TypeError: cry() missing 1 required positional argument: 'self'

看错误是少了一个参数,说明当类自己调用函数属性的时候,不会自己传入self,cry函数需要一个参数self,所以报错了,所以正确的使用是

class Cat:
    weight = 5;
    def __init__(self,name,gender,type):
        self.name = name
        self.gender = gender
        self.type = type

    def cry(self): #没有写self
        print('一条小猫喵喵')
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

cat =  Cat('毛球','公','波斯猫')
Cat.cry(cat) #类调用自己的函数属性,不传入参数

所以只有当对象去调用类的函数属性或者说方法的时候才会自动传入self属性,类自己调用时候不会,要自己传入实例。

当然我们一般不这么使用类来调用自己的函数属性,我们可以使用类方法来实现调用

class Cat:
    weight = 5;
    def __init__(self,name,gender,type):
        self.name = name
        self.gender = gender
        self.type = type

    @classmethod
    def cry(cls): #没有写self        print('一条小猫喵喵')
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

Cat.cry()

结果:

一条小猫喵喵

这里看到改动的地方,是传入的cls, 就是类自己,classmethod类静态方法实现类调用自己的函数属性时候不需要显示传入cls参数,而是自动传入,classmethod类静态方法实际就是绑定了类和自己的函数属性。

3.3 实例化到底做了什么(__init__方法)

当对象实例化的时候,会先去执行__init__函数,对象会去__init__里面找到自己的数据属性

class Cat:
    weight = 5;
    def __init__(self,name,gender,type):
        print('开始初始化')
        self.name = name
        self.gender = gender
        self.type = type
        print('结束初始化')


    def cry(self): #没有写self
        print('一条小猫喵喵')
    def run(self):
        print('一条[%s]小猫正在跑' % self.type)

cat=Cat('毛球','公','波斯猫') #实例化
print(cat.__dict__)

结果:

开始初始化
结束初始化
{'name': '毛球', 'gender': '公', 'type': '波斯猫'}

看到__init__函数里面已经执行了,对象的数据属性也得到了。

今天说到这里,个人意见,望指教。

更多源代码文章请关注:pythonislover

目录
相关文章
|
19天前
|
存储 安全 测试技术
Python面试题精选及解析
本文详解Python面试中的六大道经典问题,涵盖列表与元组区别、深浅拷贝、`__new__`与`__init__`、GIL影响、协程原理及可变与不可变类型,助你提升逻辑思维与问题解决能力,全面备战Python技术面试。
|
21天前
|
数据采集 数据挖掘 测试技术
Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析
本文对比了Python与Go在爬虫开发中的特点。Python凭借Scrapy等框架在开发效率和易用性上占优,适合快速开发与中小型项目;而Go凭借高并发和高性能优势,适用于大规模、长期运行的爬虫服务。文章通过代码示例和性能测试,分析了两者在并发能力、错误处理、部署维护等方面的差异,并探讨了未来融合发展的趋势。
89 0
|
14天前
|
安全 JavaScript Java
Python中None与NoneType的真相:从单例对象到类型系统的深度解析
本文通过10个真实场景,深入解析Python中表示“空值”的None与NoneType。从单例模式、函数返回值,到类型注解、性能优化,全面揭示None在语言设计与实际编程中的核心作用,帮助开发者正确高效地处理“无值”状态,写出更健壮、清晰的Python代码。
92 3
|
20天前
|
存储 程序员 数据处理
Python列表基础操作全解析:从创建到灵活应用
本文深入浅出地讲解了Python列表的各类操作,从创建、增删改查到遍历与性能优化,内容详实且贴近实战,适合初学者快速掌握这一核心数据结构。
98 0
|
20天前
|
存储 小程序 索引
Python变量与基础数据类型:整型、浮点型和字符串操作全解析
在Python编程中,变量和数据类型是构建程序的基础。本文介绍了三种基本数据类型:整型(int)、浮点型(float)和字符串(str),以及它们在变量中的使用方式和常见操作。通过理解变量的动态特性、数据类型的转换与运算规则,初学者可以更高效地编写清晰、简洁的Python代码,为后续学习打下坚实基础。
111 0
|
21天前
|
并行计算 算法 Java
Python3解释器深度解析与实战教程:从源码到性能优化的全路径探索
Python解释器不止CPython,还包括PyPy、MicroPython、GraalVM等,各具特色,适用于不同场景。本文深入解析Python解释器的工作原理、内存管理机制、GIL限制及其优化策略,并介绍性能调优工具链及未来发展方向,助力开发者提升Python应用性能。
94 0
|
30天前
|
存储 监控 安全
Python剪贴板监控实战:clipboard-monitor库的深度解析与扩展应用
本文介绍了基于Python的剪贴板监控技术,结合clipboard-monitor库实现高效、安全的数据追踪。内容涵盖技术选型、核心功能开发、性能优化及实战应用,适用于安全审计、自动化办公等场景,助力提升数据管理效率与安全性。
68 0
|
6月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
523 29
|
6月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
166 4
|
6月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

推荐镜像

更多