您现在的位置是:首页 > Python 当前栏目 Python之对象 Python 模块 对象 2023-03-02 10:32:21 时间 # Python之对象 # \- 对象是内存中专门用来存储数据的一块区域。 \- 对象中可以存放各种数据(比如:数字、布尔值、代码) \- 对象由三部分组成: 1.对象的标识(id) 2.对象的类型(type) 3.对象的值(value) ## 面向对象(OOP) ## \- Python是一门面向对象的编程语言 \- 所谓的面向对象的语言,简单理解就是语言中的所有操作都是通过对象来进行的 \- 面向过程的编程的语言 \- 面向过程指将我们的程序的逻辑分解为一个一个的步骤, 通过对每个步骤的抽象,来完成程序 \- 面向过程的编程思想将一个功能分解为一个一个小的步骤, 我们通过完成一个一个的小的步骤来完成一个程序 \- 这种编程方式,符合我们人类的思维,编写起来相对比较简单 \- 但是这种方式编写代码的往往只适用于一个功能, 如果要在实现别的功能,即使功能相差极小,也往往要重新编写代码, 所以它可复用性比较低,并且难于维护 \- 面向对象的编程语言 \- 面向对象的编程语言,关注的是对象,而不关注过程 \- 对于面向对象的语言来说,一切都是对象 ## 类(class) ## \- 类,简单理解它就相当于一个图纸。在程序中我们需要根据类来创建对象 \- 类就是对象的图纸! \- 我们也称对象是类的实例(instance) \- 如果多个对象是通过一个类创建的,我们称这些对象是一类对象 \- 像 int() float() bool() str() list() dict() .... 这些都是类 \- a = int(10) \# 创建一个int类的实例 等价于 a = 10 \- 我们自定义的类都需要使用大写字母开头,使用大驼峰命名法(帕斯卡命名法)来对类命名 \- 类也是一个对象! \- 类就是一个用来创建对象的对象! \- 类是type类型的对象,定义类实际上就是定义了一个type类型的对象 ## 类的定义 ## 在类的代码块中,我们可以定义变量和函数 在类中我们所定义的变量,将会成为所有的实例的公共属性 所有实例都可以访问这些变量 在类中也可以定义函数,类中的定义的函数,我们称为方法 这些方法可以通过该类的所有实例来访问 调用方法,对象.方法名() 方法调用和函数调用的区别 如果是函数调用,则调用时传几个参数,就会有几个实参 但是如果是方法调用,默认传递一个参数,所以方法中至少要定义一个形参 在类中可以定义一些特殊方法(魔术方法) 特殊方法都是以\_\_开头,\_\_结尾的方法 特殊方法不需要我们自己调用,不要尝试去调用特殊方法 特殊方法将会在特殊的时刻自动调用 init会在对象创建以后离开执行 init可以用来向新创建的对象中初始化属性 调用类创建对象时,类后边的所有参数都会依次传递到init()中 封装是面向对象的三大特性之一 封装指的是隐藏对象中一些不希望被外部所访问到的属性或方法 如何隐藏一个对象中的属性? \- 将对象的属性名,修改为一个外部不知道的名字 如何获取(修改)对象中的属性? \- 需要提供一个getter和setter方法使外部可以访问到属性 \- getter 获取对象中的指定属性(get\_属性名) \- setter 用来设置对象的指定属性(set\_属性名) 使用封装,确实增加了类的定义的复杂程度,但是它也确保了数据的安全性 1.隐藏了属性名,使调用者无法随意的修改对象中的属性 2.增加了getter和setter方法,很好的控制的属性是否是只读的 如果希望属性是只读的,则可以直接去掉setter方法 如果希望属性不能被外部访问,则可以直接去掉getter方法 3.使用setter方法设置属性,可以增加数据的验证,确保数据的值是正确的 4.使用getter方法获取属性,使用setter方法设置属性 可以在读取属性和修改属性的同时做一些其他的处理 5.使用getter方法可以表示一些计算的属性 可以为对象的属性使用双下划线开头,\_\_xxx 双下划线开头的属性,是对象的隐藏属性,隐藏属性只能在类的内部访问,无法通过对象访问 其实隐藏属性只不过是Python自动为属性改了一个名字 实际上是将名字修改为了,\_类名\_\_属性名 比如 \_\_name -> \_Person\_\_name 使用\_\_开头的属性,实际上依然可以在外部访问,所以这种方式我们一般不用 一般我们会将一些私有属性(不希望被外部访问的属性)以\_开头 一般情况下,使用\_开头的属性都是私有属性,没有特殊需要不要修改私有属性 property装饰器,用来将一个get方法,转换为对象的属性 添加为property装饰器以后,我们就可以像调用属性一样使用get方法 使用property装饰的方法,必须和属性名是一样的 setter方法的装饰器:@属性名.setter 有一个类,能够实现我们需要的大部分功能,但是不能实现全部功能 如何能让这个类来实现全部的功能呢? ① 直接修改这个类,在这个类中添加我们需要的功能 \- 修改起来会比较麻烦,并且会违反OCP原则 ② 直接创建一个新的类 \- 创建一个新的类比较麻烦,并且需要大量的进行复制粘贴,会出现大量的重复性代码 ③ 直接从Animal类中来继承它的属性和方法 \- 继承是面向对象三大特性之一 \- 通过继承我们可以使一个类获取到其他类中的属性和方法 \- 在定义类时,可以在类名后的括号中指定当前类的父类(超类、基类、super) 子类(衍生类)可以直接继承父类中的所有的属性和方法 通过继承可以直接让子类获取到父类的方法或属性,避免编写重复性的代码,并且也符合OCP原则 所以我们经常需要通过继承来对一个类进行扩展 在创建类时,如果省略了父类,则默认父类为object object是所有类的父类,所有类都继承自object,issubclass() 检查一个类是否是另一个类的子类,isinstance()用来检查一个对象是否是一个类的实例 如果在子类中如果有和父类同名的方法,则通过子类实例去调用方法时,会调用子类的方法而不是父类的方法,这个特点我们成为叫做方法的重写(覆盖,override)。 当我们调用一个对象的方法时,会优先去当前对象中寻找是否具有该方法,如果有则直接调用,如果没有,则去当前对象的父类中寻找,如果父类中有则直接调用父类中的方法, 如果没有,则去父类的父类中寻找,以此类推,直到找到object,如果依然没有找到,则报错。 父类中的所有方法都会被子类继承,包括特殊方法,也可以重写特殊方法,super() 可以用来获取当前类的父类,并且通过super()返回对象调用父类方法时,不需要传递self; 在Python中是支持多重继承的,也就是我们可以为一个类同时指定多个父类 可以在类名的()后边添加多个类,来实现多重继承 多重继承,会使子类同时拥有多个父类,并且会获取到所有父类中的方法 在开发中没有特殊的情况,应该尽量避免使用多重继承,因为多重继承会让我们的代码过于复杂 如果多个父类中有同名的方法,则会现在第一个父类中寻找,然后找第二个,然后找第三个。。。 前边父类的方法会覆盖后边父类的方法;类名.\_\_bases\_\_ 这个属性可以用来获取当前类的所有父类 。 多态是面向对象的三大特征之一,多态从字面上理解是多种形态,一个对象可以以不同的形态去呈现。 面向对象的三大特征: 封装 \- 确保对象中的数据安全 继承 \- 保证了对象的可扩展性 多态 \- 保证了程序的灵活性 \- 类和对象都是对现实生活中的事物或程序中的内容的抽象 \- 实际上所有的事物都由两部分构成: 1.数据(属性) 2.行为(方法) 定义一个类,类属性:直接在类中定义的属性是类属性,类属性可以通过类或类的实例访问到,但是类属性只能通过类对象来修改,无法通过实例对象修改实例属性; 实例属性,通过实例对象添加的属性属于实例属性,实例属性只能通过实例对象来访问和修改,类对象无法访问修改,类方法:在类内部使用 @classmethod 来修饰的方法属于类方法,类方法的第一个参数是cls,也会被自动传递,cls就是当前的类对象,类方法和实例方法的区别,实例方法的第一个参数是self,而类方法的第一个参数是cls,类方法可以通过类去调用,也可以通过实例调用,没有区别;实例方法:在类中定义,以self为第一个参数的方法都是实例方法,实例方法在调用时,Python会将调用对象作为self传入,实例方法可以通过实例和类去调用,当通过实例调用时,会自动将当前调用对象作为self传入,当通过类调用时,不会自动传递self,此时我们必须手动传递self;静态方法:在类中使用 @staticmethod 来修饰的方法属于静态方法,静态方法不需要指定任何的默认参数,静态方法可以通过类和实例去调用,静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类中的函数,静态方法一般都是一些工具方法,和当前类无关;实例属性,通过实例对象添加的属性属于实例属性。 \- 在类的代码块中,我们可以定义变量和函数, 变量会成为该类实例的公共属性,所有的该类实例都可以通过 对象.属性名 的形式访问 函数会成为该类实例的公共方法,所有该类实例都可以通过 对象.方法名() 的形式调用方法 \- 注意: 方法调用时,第一个参数由解析器自动传递,所以定义方法时,至少要定义一个形参! \- 实例为什么能访问到类中的属性和方法 类中定义的属性和方法都是公共的,任何该类实例都可以访问 \- 属性和方法查找的流程 当我们调用一个对象的属性时,解析器会先在当前对象中寻找是否含有该属性, 如果有,则直接返回当前的对象的属性值, 如果没有,则去当前对象的类对象中去寻找,如果有则返回类对象的属性值, 如果类对象中依然没有,则报错! \- 类对象和实例对象中都可以保存属性(方法) \- 如果这个属性(方法)是所有的实例共享的,则应该将其保存到类对象中 \- 如果这个属性(方法)是某个实例独有,则应该保存到实例对象中 \- 一般情况下,属性保存到实例对象中 而方法需要保存到类对象中 在程序中没有被引用的对象就是垃圾,这种垃圾对象过多以后会影响到程序的运行的性能,所以我们必须进行及时的垃圾回收,所谓的垃圾回收就是讲垃圾对象从内存中删除,在Python中有自动的垃圾回收机制,它会自动将这些没有被引用的对象删除, 所以我们不用手动处理垃圾回收。 特殊方法,也称为魔术方法,特殊方法都是使用\_\_开头和结尾的,特殊方法一般不需要我们手动调用,需要在一些特殊情况下自动执行;\_\_str\_\_()这个特殊方法会在尝试将对象转换为字符串的时候调用,它的作用可以用来指定对象转换为字符串的结果 (print函数),\_\_repr\_\_()这个特殊方法会在对当前对象使用repr()函数时调用,它的作用是指定对象在 ‘交互模式’中直接输出的效果 。 ## 类的基本结构 ## class 类名(\[父类\]) : 公共的属性... \# 对象的初始化方法 def \_\_init\_\_(self,...): ... \# 其他的方法 def method\_1(self,...): ... def method\_2(self,...): ... ## 模块(module) ## 模块化,模块化指将一个完整的程序分解为一个一个小的模块 通过将模块组合,来搭建出一个完整的程序 不采用模块化,统一将所有的代码编写到一个文件中 采用模块化,将程序分别编写到多个文件中 模块化的有点: ① 方便开发 ② 方便维护 ③ 模块可以复用! 在Python中一个py文件就是一个模块,要想创建模块,实际上就是创建一个python文件 注意:模块名要符号标识符的规范 在一个模块中引入外部模块 ① import 模块名 (模块名,就是python文件的名字,注意不要py) ② import 模块名 as 模块别名 \- 可以引入同一个模块多次,但是模块的实例只会创建一个 \- import可以在程序的任意位置调用,但是一般情况下,import语句都会统一写在程序的开头 \- 在每一个模块内部都有一个\_\_name\_\_属性,通过这个属性可以获取到模块的名字 \- \_\_name\_\_属性值为 \_\_main\_\_的模块是主模块,一个程序中只会有一个主模块 主模块就是我们直接通过 python 执行的模块 import m,访问模块中的变量:模块名.变量名,也可以只引入模块中的部分内容,语法 from 模块名 import 变量,变量....,也可以为引入的变量使用别名,语法:from 模块名 import 变量 as 别名。 可以在模块中定义变量,在模块中定义的变量,在引入模块后,就可以直接使用了,可以在模块中定义函数,同样可以通过模块访问到,添加了\_的变量,只能在模块内部访问,在通过import \* 引入时,不会引入\_开头的变量,也可以定义类,编写测试代码,这部分代码,只要当当前文件作为主模块的时候才需要执行,而当模块被其他模块引入时,不需要执行的,此时我们就必须要检查当前模块是否是主模块 。 ## 包 Package ## 包也是一个模块,当我们模块中代码过多时,或者一个模块需要被分解为多个模块时,这时就需要使用到包,普通的模块就是一个py文件,而包是一个文件夹,包中必须要一个一个 \_\_init\_\_.py 这个文件,这个文件中可以包含有包中的主要内容,\_\_pycache\_\_ 是模块的缓存文件,py代码在执行前,需要被解析器先转换为机器码,然后再执行,所以我们在使用模块(包)时,也需要将模块的代码先转换为机器码然后再交由计算机执行,而为了提高程序运行的性能,python会在编译过一次以后,将代码保存到一个缓存文件中,这样在下次加载这个模块(包)时,就可以不再重新编译而是直接加载缓存中编译好的代码即可。 ## 开箱即用 ## 为了实现开箱即用的思想,Python中为我们提供了一个模块的标准库 在这个标准库中,有很多很强大的模块我们可以直接使用, 并且标准库会随Python的安装一同安装 sys模块,它里面提供了一些变量和函数,使我们可以获取到Python解析器的信息 或者通过函数来操作Python解析器 引入sys模块 import sys pprint 模块它给我们提供了一个方法 pprint() 该方法可以用来对打印的数据做简单的格式化 import pprint sys.argv 获取执行代码时,命令行中所包含的参数 该属性是一个列表,列表中保存了当前命令的所有参数 print(sys.argv) sys.modules 获取当前程序中引入的所有模块 modules是一个字典,字典的key是模块的名字,字典的value是模块对象 pprint.pprint(sys.modules) sys.path 他是一个列表,列表中保存的是模块的搜索路径 \['C:\\\\Users\\\\lx\\\\Desktop\\\\code', 'C:\\\\dev\\\\python\\\\python36\\\\python36.zip', 'C:\\\\python\\\\python36\\\\DLLs', 'C:\\\\python\\\\python36\\\\lib', 'C:\\\\python\\\\python36', 'C:\\\\python\\\\python36\\\\lib\\\\site-packages'\] pprint.pprint(sys.path) sys.platform 表示当前Python运行的平台 print(sys.platform) sys.exit() 函数用来退出程序 sys.exit('程序出现异常,结束!') print('hello') os 模块让我们可以对操作系统进行访问 import os os.environ 通过这个属性可以获取到系统的环境变量 pprint.pprint(os.environ\['path'\]) os.system() 可以用来执行操作系统的名字 os.system('dir') 本文地址: Python之对象 相关文章 Python 文件 Python 模块与包 Python 元组和集合 Python 函数与变量作用域 Python 基础篇(一) Python 基础篇(二) Python 基础篇(三) Python 基础篇(四) Python 基础篇 (五) Python 异常处理 python实现微信自动聊天 Python一些类库的基本操作 Python爬虫之分布式爬虫 Python爬虫之scrapy框架学习 Python爬虫之selenium学习 Python爬虫模拟登陆和异步爬虫 Python问题合集 Python爬虫基础 Python进阶 Python基础