目录

面向对象概述

面向对象的一种实现

类的相关知识

对象的相关知识

面向对象属性的查改增删操作

类属性的查改增删

对象属性的查改增删

关于类、对象属性容易混淆额或忽略的地方的说明


面向对象概述

编程发展至今有面向过程编程、函数式编程、面向对象编程三大流派,未来不知道会不会有面向数据的编程。

Python支持面向对象编程,为什么要面向对象呢?面向对象是个啥?我的粗浅理解,就是将一系列相干的数据、方法封装到一起形成实例,并限制实例的数据、方法调用方式,通过对这个实例的控制达到简化编程过程,提高代码可读性的目的。比如,C++怎么实现面向对象的呢,数据用struct结构封装,成员函数其实就是普通的函数但入参多了个this指针,在调用函数的时候this指针取struct实例的地址,再把这个特殊的struct加个关键字class,这样就实现了class类和类的绝大多数功能。这就是面向对象的实现方法。Java也不例外。那么Python呢?

面向对象的一种实现

Python中,属性数据可以用字典封装,函数可以作为对象被封装在字典里面,函数可以嵌套从而限制其不能在作用域外被调用。根据这个思想,我们可以定义一个狗函数dog,嵌套函数定义狗的两个方法bark、wag_tail,再用字典封装狗的属性。这样就实现了面向对象的设计。调用函数的时候,传入自己作为参数,实际上就是类似C++里面的this指针。

def dog(name, type, gender):def bark(dog):"""狗会叫:return:"""print('%s is wang!wang!' % dog['name'])passdef wag_tail(dog):"""狗会摇尾巴:return:"""print('%s wag tail %s' % (dog['name'], dog['type']))passdef init():"""初始化狗,名字,品种,公母会叫,会摇尾巴:return:"""dog_property = {'name': name,'type': type,'gender': gender,'bark': bark,  # 将会叫函数作为属性'wag_tail': wag_tail,  # 将会摇尾巴函数作为属性}return dog_propertypassret = init()return retpassd1 = dog('Snoopy', '哈士奇', 'female')
print(d1)
d1['bark'](d1)
d1['wag_tail'](d1)
# {'name': 'Snoopy', 'type': '哈士奇', 'gender': 'femal', 'bark': <function dog.<locals>.bark at 0x00000000028A50D0>, 'wag_tail': <function dog.<locals>.wag_tail at 0x0000000003BAA620>}
# Snoopy is wang!wang!
# Snoopy wag tail 哈士奇d2 = dog('旺财', '柴犬', 'male')
print(d2)
d2['bark'](d2)
d2['wag_tail'](d2)
# {'name': '旺财', 'type': '柴犬', 'gender': 'mail', 'bark': <function dog.<locals>.bark at 0x0000000003BAA6A8>, 'wag_tail': <function dog.<locals>.wag_tail at 0x0000000003BAA730>}
# 旺财 is wang!wang!
# 旺财 wag tail 柴犬

类的相关知识

类描述一类事物共有的数据(属性)和动作(方法)。类本身是没有具体信息的,是一个抽象的类型。类可以具体化到对象。

class Dog:"""这是一个狗类"""fur = 'property fur'def bark():print('from bark')passdef wag_tail(self):print('from wag_tail')passpassprint(Dog)
# <class '__main__.Dog'># 调用类的方法
Dog.bark()
# from bark
Dog.wag_tail('123')
# from wag_tail# 比较dir函数的输出和类__dict__的输出
# 特别是自定义的fur、bark、wag_tail
# dir只列出属性的名字
# __dict__累出属性的名字和值
print(dir(Dog))
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
# '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
# '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__',
# '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
# '__str__', '__subclasshook__', '__weakref__', 'bark', 'fur', 'wag_tail']
print(Dog.__dict__)
# {'__module__': '__main__',
# '__doc__': '\n    这是一个狗类\n    ',
# 'fur': 'property fur',
# 'bark': <function Dog.bark at 0x0000000003BBA620>,
# 'wag_tail': <function Dog.wag_tail at 0x0000000003BBA6A8>,
# '__dict__': <attribute '__dict__' of 'Dog' objects>,
# '__weakref__': <attribute '__weakref__' of 'Dog' objects>}# Dog类里面有fur属性,可以用类名直接调用
print(Dog.fur)
# Dog的__dict__属性,查看类的属性字典
# 上面直接调用Dog.fur实际上也是用属性字典实现的
print(Dog.__dict__['fur'])print(Dog.__name__)  # 类的名字Dog
print(Dog.__doc__)  # 类的说明文档,也就是类定义后紧跟的说明"""这是一个狗类""""
print(Dog.__bases__)  # Python支持多继承,后面仔细研究,__bases__以元组形式列出了所以父类(<class 'object'>,)

对象的相关知识

我们在面向对象的一种实现那一节用函数实现了面向对象的设计。Python内置了面向对象编程的设计。

我们自己嵌套定义的初始化函数init,Python类里面有内置的__init__方法来初始化,__init__必须有self入参,自动将实例本身传给self。自动进行初始化和返回实例,因此__init__不用return。类创建实例的过程和函数调用类似。

对象只保存数据属性,不保存方法属性。这样,每个对象存自己的数据,共享一份方法。

对象调用方法的时候,将对象本身传给self参数。通过self来访问对象各自的数据。

class Dog:"""这是一个狗类"""fur = 'property fur'def __init__(self, name, breed, gender):self.name = nameself.breed = breed  # 品种self.gender = genderpassdef bark(self):print('%s 汪汪!' % self.name)passdef wag_tail(self):print('%s 摇尾巴' % self.name)passpassd1 = Dog('旺财', '中华田园犬', 'male')
print(d1)
# <__main__.Dog object at 0x00000000026D9BA8># __dict__查看对象的属性字典
# 对象只保存数据属性,不保存方法
print(d1.__dict__)
# {'name': '旺财', 'type': '中华田园犬', 'gender': 'male'}# 调用对象的属性
# 对象有的(__init__)直接调用 name
# 对象没有的,到外面的作用域类里面去找 fur
print(d1.name, d1.fur)# 对象调用方法是调用类的方法,调用时将对象传给self参数
Dog.bark(d1)
d1.bark()
# 旺财 汪汪!

面向对象属性的查改增删操作

Python的面向对象支持属性的查改增删。类的属性、对象的属性都可以查改增删。

以前用Java知道可以查、改属性,学了Python才知道属性还可以增、删,而且是数据属性和方法属性的查改增删,真牛逼。

类属性的查改增删

我们做查改增删,对比类的属性字典__dict__的内容和调用情况。直接看代码例子……

class Dog:"""这是一个狗类"""fur = 'property fur'def __init__(self, name, breed, gender):self.name = nameself.breed = breed  # 品种self.gender = genderpassdef bark(self):print('%s 汪汪!' % self.name)passdef wag_tail(self):print('%s 摇尾巴' % self.name)passdef eat_food(self, food):print('%s 吃 %s' % (self.name, food))passpassd1 = Dog('旺财', '中华田园犬', 'male')
d2 = Dog('123', '中华田园犬', 'male')# ========== 类属性的查 ==========print(Dog.fur)
# property furprint('查询', Dog.__dict__)
# 查询
# {'__module__': '__main__',
# '__doc__': '\n    这是一个狗类\n    ',
# 'fur': 'property fur',
# '__init__': <function Dog.__init__ at 0x0000000003BAA620>,
# 'bark': <function Dog.bark at 0x0000000003BAA6A8>,
# 'wag_tail': <function Dog.wag_tail at 0x0000000003BAA730>,
# 'eat_food': <function Dog.eat_food at 0x0000000003BAA7B8>,
# '__dict__': <attribute '__dict__' of 'Dog' objects>,
# '__weakref__': <attribute '__weakref__' of 'Dog' objects>}# ========== 类属性的改 ==========Dog.fur = 'modify fur'
print(Dog.fur)# 改方法属性
def test(self):print('%s 是 %s 品种' % (self.name, self.breed))pass# 方法属于类,可以在类上改方法属性
# 修改后调用eat_food其实调用的是test
Dog.eat_food = test
d1.eat_food()
# 旺财 是 中华田园犬 品种# 可以看到eat_food的地址已经发生了变化,变成了test函数的地址
print(test)
# <function test at 0x00000000028950D0>
print('修改', Dog.__dict__)
# 修改
# {'__module__': '__main__',
# '__doc__': '\n    这是一个狗类\n    ',
# 'fur': 'modify fur',
# '__init__': <function Dog.__init__ at 0x0000000003BAA620>,
# 'bark': <function Dog.bark at 0x0000000003BAA6A8>,
# 'wag_tail': <function Dog.wag_tail at 0x0000000003BAA730>,
# 'eat_food': <function test at 0x00000000028B50D0>,
# '__dict__': <attribute '__dict__' of 'Dog' objects>,
# '__weakref__': <attribute '__weakref__' of 'Dog' objects>}# ========== 类属性的增 ==========# 增加数据属性——项圈
Dog.ring = 'leather'# 增加方法属性
def play_ball(self):print('%s 玩球' % self.name)pass# 方法属于类,可以在类上增加方法属性play_ball
Dog.play_ball = play_ball
d1.play_ball()
# 旺财 玩球# 可以看到增加属性以后__dict__里面增加了ring属性、play_ball方法
print('增加', Dog.__dict__)
# 增加
# {'__module__': '__main__',
# '__doc__': '\n    这是一个狗类\n    ',
# 'fur': 'modify fur',
# '__init__': <function Dog.__init__ at 0x0000000003BAA620>,
# 'bark': <function Dog.bark at 0x0000000003BAA6A8>,
# 'wag_tail': <function Dog.wag_tail at 0x0000000003BAA730>,
# 'eat_food': <function test at 0x00000000028C50D0>,
# '__dict__': <attribute '__dict__' of 'Dog' objects>,
# '__weakref__': <attribute '__weakref__' of 'Dog' objects>,
# 'ring': 'leather',
# 'play_ball': <function play_ball at 0x0000000003BAA7B8>}# ========== 类属性的删 ==========# 删除数据属性
del Dog.ring# 删除方法
# 方法属于类,可以在类上删除
del Dog.eat_food# 注意比较删除前后的属性字典,删除ring以后就没有ring了,删除以后就没有eat_food方法了
print('删除', Dog.__dict__)
# 删除
# {'__module__': '__main__',
# '__doc__': '\n    这是一个狗类\n    ',
# 'fur': 'modify fur',
# '__init__': <function Dog.__init__ at 0x0000000003BAA620>,
# 'bark': <function Dog.bark at 0x0000000003BAA6A8>,
# 'wag_tail': <function Dog.wag_tail at 0x0000000003BAA730>,
# '__dict__': <attribute '__dict__' of 'Dog' objects>,
# '__weakref__': <attribute '__weakref__' of 'Dog' objects>,
# 'play_ball': <function play_ball at 0x0000000003BAA7B8>}

对象属性的查改增删

我们做查改增删,对比对象的属性字典__dict__的内容和调用情况。直接看代码例子……

class Dog:"""这是一个狗类"""fur = 'property fur'def __init__(self, name, breed, gender):self.name = nameself.breed = breed  # 品种self.gender = genderpassdef bark(self):print('%s 汪汪!' % self.name)passdef wag_tail(self):print('%s 摇尾巴' % self.name)passdef eat_food(self, food):print('%s 吃 %s' % (self.name, food))passdef play_ball(self, ball):print('%s 玩 %s' % (self.name, ball))passpassd1 = Dog('旺财', '中华田园犬', 'male')
d2 = Dog('123', '中华田园犬', 'male')# ========== 对象属性的查 ==========print(d1.name)
print(d2.name)
# 旺财
# 123d1.play_ball('篮球')
d2.play_ball('篮球')
print(d1.play_ball)
# 旺财 玩 篮球
# 123 玩 篮球
# <bound method Dog.play_ball of <__main__.Dog object at 0x0000000003B9D8D0>>
# 打印d1.play_ball实际访问的是类Dog.play_ballprint(d1.__dict__)
print(d2.__dict__)
# {'name': '旺财', 'breed': '中华田园犬', 'gender': 'male'}
# {'name': '123', 'breed': '中华田园犬', 'gender': 'male'}# ========== 对象属性的增 ==========# 增加数据属性
d1.age = 10
print(d1.__dict__)
print(d2.__dict__)
# {'name': '旺财', 'breed': '中华田园犬', 'gender': 'male', 'age': 10}
# {'name': '123', 'breed': '中华田园犬', 'gender': 'male'}# 对象可以增加方法属性吗?
# 理论和技术上可以这么做,那么增加的方法就只属于这个对象。
# 这违背了对象实例只有数据属性的原则,不要这么做!!!# ========== 对冲属性的改 ==========d1.age = 17
print(d1.age)
# 17# ========== 对象属性的删 ==========del d1.age
del d2.name
print(d1.__dict__)
print(d2.__dict__)
# {'name': '旺财', 'breed': '中华田园犬', 'gender': 'male'}
# {'breed': '中华田园犬', 'gender': 'male'}

关于类、对象属性容易混淆额或忽略的地方的说明

挺绕的,直接看代码例子里的注释吧……

fur = 'yellow'class Dog:"""这是一个狗类"""fur = 'property fur'li = ['a', 'b']li2 = ['x', 'y']def __init__(self, name, breed, gender):self.name = nameself.breed = breed  # 品种self.gender = genderprint('--->', fur)passpass# __init__里面既不是self的也不是作用域内的ring
# 那么就是全局的ring,和类已经没有关系了
d1 = Dog('旺财', '中华田园犬', 'male')
d2 = Dog('123', '中华田园犬', 'male')
# ---> yellow
# ---> yellow# 数据属性就是属于各自的Dog.fur = 'yellow'
d1.fur = 'white'
d2.fur = 'gray'
print('类的毛:', Dog.fur)
print('对象d1的毛:', d1.fur)
print('对象d2的毛:', d2.fur)
# 类的毛: yellow
# 对象d1的毛: white
# 对象d2的毛: gray# 由于li是类的属性
# 通过d1调用li的append并没有给对象新增任何属性
# 所以修改的就是类的li,因此li都是['a','b','c']
d1.li.append('c')
print(Dog.li)
print(d1.li)
print(d2.li)
# ['a', 'b', 'c']
# ['a', 'b', 'c']
# ['a', 'b', 'c']# 由于li2也是类的属性
# 但是,d2.li2=是给d1对象新增了一个属性,这与上面append不同
# 所以修改的是d2.li2的属性
d1.li2 = [1, 2, 3]
print(Dog.li2)
print(d1.li2)
print(d2.li2)
# ['x', 'y']
# [1, 2, 3]
# ['x', 'y']# 此时,再对d1和d2的li2操作,已经有本质的不同了
# d1的li2是d1自己的
# d2的li2是类的
# 这一点可以从对象的__dict__可以看出
d1.li2.append('c')
d2.li2.append('z')
print(Dog.li2)
print(d1.li2)
print(d2.li2)
print(d1.__dict__)
print(d2.__dict__)
# ['x', 'y', 'z']
# [1, 2, 3, 'c']
# ['x', 'y', 'z']
# {'name': '旺财', 'breed': '中华田园犬', 'gender': 'male', 'fur': 'white', 'li2': [1, 2, 3, 'c']}
# {'name': '123', 'breed': '中华田园犬', 'gender': 'male', 'fur': 'gray'}

Python基础19-面向对象基础相关推荐

  1. Javascript基础与面向对象基础~第四讲 Javascript中的类对象

    今天来说JS中如何实现类(class),事实上本应该昨天晚上写的,可我失言了,在些说一声"抱歉"!JS中的类是JS面向对象的基础,也是我最拿手的东西,你写的代码能否提高一个层次,一 ...

  2. python面向对象基础_python面向对象基础

    面向对象基础 一.面向对象和面向过程 面向过程: 优点:复杂问题流程化,进而简单化 确定:可扩展性差 面向对象: 优点:可扩展性高 缺点:编写复杂度高于面向过程 二.类与对象 类即类别.种类,是面向对 ...

  3. 【Python基础】面向对象基础和特性

    Python面向对象 面向对象基础 定义类 创建对象 添加和获取对象属性 魔法方法 对象的生命周期 私有属性和私有方法 面向对象特性 封装 封装案例演练 继承 继承的传递性 方法的重写 父类的私有属性 ...

  4. python基础19 -------面向对象终结篇(介绍python对象中各种内置命令)

    一.isinstance()和issubclass()命令 1.isinstance(对象,类型) 用来判定该对象是不是此类型或者说是该对象是不是此类的对象,返回结果为True和False,如图所示. ...

  5. Python OOP:面向对象基础,定义类,创建对象/实例,self,创建多个对象,添加对象属性,访问对象属性,__init__方法,带参数的__init__,__str__方法,__del__方法

    一.理解面向对象 面向对象是⼀种抽象化的编程思想,很多编程语⾔中都有的⼀种思想. ⾯向对象就是将编程当成是⼀个事物,对外界来说,事物是直接使用的,不用去管他内部的情况.⽽编程就是设置事物能够做什么事. ...

  6. Python学习:面向对象基础练习——士兵突击(代码演示) 及 身份运算符

    1.面向对象封装案例II--士兵突击 目标 士兵突击案例 身份运算符 封装 封装 是面向对象编程的一大特点 面向对象编程的 第一步 -- 将 属性 和 方法 封装 到一个抽象的 类 中 外界 使用 类 ...

  7. 个人python学习-Day7面向对象基础(上)

    一.面向对象介绍 1.概述 面向过程:根据业务逻辑从上到下写代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象编程:将数据与函数绑定到一起,进行封装,这样能够更快速的 ...

  8. Python基础:面向对象基础 (一) 类及其属性和魔法方法

    定义类,添加和获取对象属性 # 定义类 格式如下 # class 类名: # 方法列表# 新式类定义形式 # info 是一个实例方法,第一个参数一般是self,表示实例对象本身 class Hero ...

  9. python入门笔记——面向对象基础1_5(小明爱跑步案例)

    案例: 小明爱跑步:实际项目需求如下 ①小明体重 75.0 公斤 ②小明每次跑步 会减少0.5公斤 ③小明每次吃东西 会增加 1公斤 1.案例分析: 名字提炼法,小明--人类: 属性--体重 动词提炼 ...

  10. php 面向对象基础,PHP 面向对象基础

    本文主要阐述面向对象的基本概念,如有问题,还请斧正. 首先说明,涉及的一些知识点,算是提纲吧 . 1 类的基本概念:2 对象的基本概念:3 访问控制:4 构造函数,析构函数:5魔术方法:6 接口:7 ...

最新文章

  1. linux 下 使用wget 下载 jdk资源 命令
  2. 程序包不存在?无源文件?找不到文件?找不到或无法加载主类?
  3. SQL LIKE 通配符随笔
  4. 387. First Unique Character in a String QuestionEditorial Solution
  5. mysql将不同行数结果合并成多列_将多行合并到mysql中的一行和多列
  6. Linux系统编程22:基础IO之掌握重定向的本质和使用dup2完成重定向
  7. PTA 数据结构与算法题目集 6-1
  8. 什么专业的会学python语言_还在纠结学什么编程语言吗?Python可能会“教”你做人...
  9. html网页设计课程设计总结,网页制作课程设计报告总结.doc
  10. bch matlab,求助!关于matlab中BCH码的弱问题
  11. c语言程序中文复制到word变乱码,怎么复制C程序代码到Word不会有乱码,不会有乱字等情况...
  12. Google浏览器升级为最新打开网页时缓慢 “正在建立安全连接..........”解决方法
  13. 如何自定义炫酷浏览器主页
  14. 漳州可视化3d建模,智慧城市园区数字孪生可视化,数字孪生可视化工厂
  15. matlab中的regress函数总结
  16. 鸿蒙实力等级划分,从综漫开始的万界之旅
  17. rfc959 FTP传输协议
  18. (理财六)贷款用途的分类
  19. tensorflow function笔记: tf.tile
  20. 游戏开发物理引擎PhysX研究系列:将重力模拟关闭

热门文章

  1. dubbo yml配置_利用springboot+dubbo,构建分布式微服务,全程注解开发(一)
  2. XML 解析XML文档 XML约束
  3. 实验1 应用SQL Server进行数据定义和管理
  4. Java中的Map集合遍历总结(详尽版)
  5. python查看所有异常_如何获取python异常发生的实际行号?
  6. 你真的会用 CocoaPods 吗?
  7. iOS 模仿支付宝支付到账推送,播报钱数
  8. 玩转“网上邻居”之网络配置(二)
  9. houdini + maya的pulldownit
  10. 通讯组基本管理任务一