Python学习之面向对象

本文介绍了Python的面向对象编程,包括类的创建、属性与方法(类属性、实例方法、静态方法、类方法)、动态绑定属性和方法、封装、继承、多态。通过实例详细解析了__init__、__new__、__init__的区别以及浅拷贝和深拷贝的概念。还涉及了模块的使用,如导入、主程序运行、包的管理。最后提到了文件操作和os模块的功能。

1. 前言

上次学习了Python的基本语法,这次学面向对象,本博客主要介绍Python的面向对象和一些常用的类。本博客不太适合小白,适合有一定的编程基础的童鞋.
学习资料主要来自两处:
B站Python教程全套
Python3 面向对象

本文原创,创作不易,转载请注明!!!
本文链接
个人博客:https://ronglin.fun/?p=211
PDF链接:见博客网站
优快云: https://blog.youkuaiyun.com/RongLin02/article/details/115772156

2. 面向对象

Java和C++中,面向对象编程的思想很常用,两大思想,面向过程和面向对象.
有关面向对象的相关概念不在赘述,直接引入Python有关面向对象语法,一句话概括,Python中一切皆对象.

2.1. 类

2.1.1. 类的创建

创建语法:

class 类名:
    语句1
    语句2

和Java类似.类名一般首字母大写,其余小写,例子:

class Student:
    pass


print(id(Student))
print(type(Student))
print(Student)

输出结果:

2849693220416
<class 'type'>
<class '__main__.Student'>

2.1.2. 属性与方法

这些和Java中的概念是一样的
一个类可以有:类属性,实例方法,静态方法,类方法
先看一个例子:

class Student:
    codeLanguage = 'Python'  # 类属性

    def __init__(self, name, age):
        print('Student类被创建')
        print('编程语言是', self.codeLanguage)
        self.name = name
        self.age = age

    @staticmethod
    def learn():  # 静态方法
        print('我正在学习!!!')

    @classmethod
    def eye(cls):  # 类方法
        print('我在看书')


stu1 = Student('张飞', 18)
print(stu1.name, '今年', stu1.age, '岁')
print(Student.codeLanguage)

输出结果

Student类被创建
编程语言是 Python
张飞 今年 18 岁
Python

其中,__init__有点类似于 Java中的构造函数,当创建了这个类的实例时就会调用该方法.而self就先当于Java中的this,self在Python中代表类的实例.
使用一个类就是 实例名 = 类名(参数),调用方法的话,就是实例名.方法名
类属性是所有实例共享的,调用方法就是 类名.属性.
静态方法也是如此,调用方法就是 类名.静态方法.定义静态方法要用@staticmethod修饰
类方法,要用@classmethod修饰

2.1.3. 动态绑定属性和方法

如果某一个实例对象,想给这个实例单独增加属性,而且同类的其他实例不能用的话,可以用 实例名.新属性名 = 值.
这样,这个新的属性名只有这个实例可以用.
在class中定义的属性,所有实例名都可以用.
同时,也可以动态绑定方法,例子如下:

class Student:
    def __init__(self, name, age):
        print('Student类被创建')
        self.name = name
        self.age = age

    @staticmethod
    def learn():  # 静态方法
        print('我正在学习!!!')

    @classmethod
    def eye(cls):  # 类方法
        print('我在看书')


stu1 = Student('张飞', 18)
stu2 = Student('孙悟空', 500)
stu1.sex = '男'
print(stu1.sex)


def eatFood():
    print('我会吃桃')


stu2.eat = eatFood
stu2.eat()

输出结果:

Student类被创建
Student类被创建
男
我会吃桃

2.2. 封装

封装是为了提高程序的安全性,Python中没有设置访问权限的修饰符,不像Java有private public project这样的访问权限修饰符.如果该属性不希望在类对象外部被访问,在属性的前边使用两个’_’.
代码如下:

class Time:
    __company = '长江'

    def __init__(self, hour, min):
        self.hour = hour
        self.min = min

    def printTime(self):
        print('时间是', self.hour, '时', self.min, '分')


tm = Time(12, 23)
tm.printTime()
print(tm.__company)

输出:

时间是 12 时 23 分
Traceback (most recent call last):
  File "XXXXXXXX.py", line 14, in <module>
    print(tm.__company)
AttributeError: 'Time' object has no attribute '__company'

访问失败,但是如果非要访问,可以通过 实例名._类名__属性访问,例如:print(tm._Time__company)就可以输出结果了.但是这是相当于一个君子约定,所以开发的时候最好不要去访问用两个’_'修饰的属性.

2.3. 继承

Python是支持多继承的,这点和C++类似
定义子类时,必须在其构造函数中调用父类的构造函数
如果一个类没有继承父类,则默认继承object类

2.3.1. 继承的语法

继承的格式:

class 子类名(父类1,父类2...):
    pass

代码实现:

class Person:
    life = '吃东西'

    def __init__(self, name, age):
        print('一个人被创建')
        self.name = name
        self.age = age

    def show(self):
        print(self.name, self.age)


class Student(Person):
    def __init__(self, name, age, score):
        super().__init__(name, age)
        print('学生被创建')
        self.score = score


stu1 = Student('雷娜', 20, 95)
stu1.show()

输出:

一个人被创建
学生被创建
雷娜 20

2.3.2. 方法的重写

有的时候,子类希望重写一下父类的方法,以便实现更多的功能.
代码:

class Person:
    life = '吃东西'

    def __init__(self, name, age):
        print('一个人被创建')
        self.name = name
        self.age = age

    def show(self):
        print(self.name, self.age)


class Student(Person):
    def __init__(self, name, age, score):
        super().__init__(name, age)
        print('学生被创建')
        self.score = score

    def show(self):
        print('分数是', self.score)
        super().show()


stu1 = Student('雷娜', 20, 95)
stu1.show()

输出结果:

一个人被创建
学生被创建
分数是 95
雷娜 20

可以看到,重写之后,就会按照子类写的方法体来执行.

2.4. 多态

多态的形式:

class Animal:
    def eat(self):
        print('动物需要吃东西')
class Cat(Animal):
    def eat(self):
        print('猫吃鱼')
class Dog(Animal):
    def eat(self):
        print('狗吃shit')
class Person:
    def eat(self):
        print('人啥都吃')

def fun(obj):
    obj.eat()

fun(Animal())
fun(Cat())
fun(Dog())
fun(Person())

输出结果:

动物需要吃东西
猫吃鱼
狗吃shit
人啥都吃

2.5. 其他笔记

2.5.1. object类

object类中封装了很多方法,一般用的比较多的之一是 重写 __str__方法,这样print打印的时候就会打印str方法中的格式了.
格式是

    def __str__(self):
        return '想要输出的内容'

调用的时候就是print(实例名)
object中还有一些特殊方法,这里推荐去官方查询API
Python/C 3.9.4 API 参考手册
着重提一下两个方法:
__new__()和__init__()
一个是创建类的,一个是用于类的初始化的

2.5.2. 拷贝

变量的赋值操作:只是形成两个变量,实际上还是指向同一个对象

拷贝有两种:
浅拷贝:Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象
用法:

import copy
stu2 = copy.copy(stu1)

其中stu1是之前已经创建好初始化完毕的类实例,stu2是新的类实例.

深拷贝:使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同.
用法:

import copy
stu2 = copy.deepcopy(stu1)

有关浅拷贝和深拷贝可以看看这篇:Python 直接赋值、浅拷贝和深度拷贝解析

3. 模块

参考资料:Python3 模块
简单的理解,模块就是一个函数或者类的集合体.就是一个.py文件

3.1. 定义模块

1.新建一个.py文件,最好不要和Python自带的模块名相同
2.在自己的程序中导入模块,导入的格式

import 模块名称 [as 别名]
from 模块名称 import 函数/类/变量

然后就可以用了,和Java中的导包差不多.
例如:

import math

print(math.pi, math.e)
print(math.pow(2, 3), type(math.pow(2, 3)))

第一种就是导入所有math模块中的所有

from math import pi

print(pi)

第二种就是只导入math中的pi

注意,import方式后边只能接包名或模块名,而from的方式可以导入变量

3.2. 主程序运行

在每个模块的定义中都包括一个记录模块名称的变量__name__,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其它程序中执行,那么它可能在解释器的顶级模块中执行。顶级模块的__name__变量的值为__main__
格式:

if __name__ == '__main__':
    pass

这句话的意思是,只有当点击运行当前.py文件时,pass那的代码才会运行

3.3. 包

一个Python程序中,可以包含很多包,而每一个包可以包含很多模块.
包就是一个分层次的目录结构,包和目录的区别是,包含__init__.py文件的目录称为包,而目录里通常不包含__init__.py文件
包的导入就是

import 包名.模块 [as 别名]

别名是这个包名.模块的别名,调用其中的变量应该 别名.变量名
例如

import package01.mymodule as mm

print(mm.str)
print(package01.mymodule.str)

两句是等效的

3.4. 常用模块

下面提到的模块网上都可以查到其用法,推荐官方api

  1. sys 与Python解释器及其环境操作相关的标准库
  2. time 提供与时间相关的各种函数标准库
  3. os 提供了访问操作系统服务功能的标准库
  4. calendar 提供与日期相关的各种函数标准库
  5. urllib 用于读取来自网上(服务器)的数据标准库
  6. json 用于使用JSON序列化和反序列化对象
  7. re 用于在字符串中执行正则表达式匹配和替换
  8. math 提供标准算术运算函数的标准库
  9. decimal 用于精确控制运算精度
  10. logging 提供了灵活的记录事件 错误等日志信息功能

3.5. 第三方模块的安装

安装格式:

pip install 模块名

使用和上面模块的使用一样,直接import导入就行了

4. 文件

.py文件在外存中是以UTF-8格式保存的(默认方式),如果要修改文本编码格式,在py文件最开始加一句#encoding=GBK,注意不要丢掉#符号
本次参考:Python3 File(文件) 方法

4.1. 文件的读写

文件操作:

file = open(filename [, mode ,encoding])
print(file.readlines())
file.close()

mode是打开方式,encoding是编码格式.每次文件用完之后记得关闭,和Java/C一样
打开方式和常用的file方法在菜鸟教程中都有,有需要请点击上方的网站自行查看
Python中file对象方法中既可以读也可以写,比Java方便一些.

4.2. with语句

with语句可以自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确的关闭,以此来达到释放资源的目的
格式:

with open('文件名','r+') as [别名]:
    语句1
    语句2

with之后就不用再手动关闭文件,其实主要还是对象实现了__enter__和__exit__方法,就算运行过程中产生了异常,也会调用__exit__退出.

4.3. os模块

参考资料:os模块视频讲解
Python3 OS 文件/目录方法
os是一个目录操作模块,os模块是Python内置的与操作系统功能和文件系统相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样,os模块与os.path模块用于对目录或文件进行操作.
os模块中很多方法都在上方网站里有,有需要的请自行查阅.

总结
Python确实比C/C++ java方便很多,用了大概5天时间快速入门熟悉了基本语法,好在自己学过C,入门python还是比较简单的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值