Python Learning Journal:Day4
类
定义
类属性、实例方法(self)、实体属性、静态方法()、类方法(cls)
class Student:
native_space = '吉林' # 类属性:直接写在类里的变量
def __init__(self, name, age):
# self.name是实体属性
self.name = name # 将局部变量name的值赋给实体属性self.name
self.age = age
# 实例方法:类之内定义
def eat(self):
print('学生在吃饭')
# 静态方法:不写self
@staticmethod
def method():
print('')
# 类方法:写cls
@classmethod
def cm(cls):
print()
对象的创建
对象 = 类名():stu = Student('张三', 20)
实例对象stu、类对象Student
示例属性:stu.name()
实例方法:stu.eat()
<==> Student.eat(stu)
类属性、类方法、静态方法的使用
类属性
print(stu.native_space) # 吉林
stu.native_space = '天津'
print(stu.native_space) # 天津
类方法:@classmethod
stu.eat()
静态方法:@staticmethod、cls
stu.method()
动态绑定属性和方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
# 实例方法:类之内定义
def eat(self):
print(self.name+'在吃饭')
动态绑定属性:增添stu2属性gender,该属性只适用于stu2。
stu2 = Student('李四', 20)
stu2.gender = '女'
print(stu2.name, stu2.age, stu2.gender) # 李四 20 女
动态绑定方法:在类外添加函数,将该函数与stu2绑定后,对于stu2而言就是stu2的方法,该“方法”只适用于stu2。
def show():
print('定义在类之外的称为函数')
stu2.show = show
stu2.show() # 定义在类之外的称为函数
封装
将数据(属性)和行为(方法)包装到类对象中
class Student:
def __init__(self, name, age):
self.name = name
self.__age = age # 加__说明不希望age在类的外部被使用
继承
支持多继承
不写父类时,默认继承object类
定义子类时,必须在其构造函数中调用父类的构造函数
语法格式:class 子类名(父类1, 父类2, ...):
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person):
def __init__(self, name, age, number):
super().__init__(name, age)
self.number = number
class Teacher(Person):
def __init__(self, name, age, teachyear):
super().__init__(name, age)
self.teachyear = teachyear
stu = Student('张三', 20, 1001)
teacher = Teacher('李红', 40, 15)
stu.info()
teacher.info()
多继承
class A(object):
pass
class B(object):
pass
class C(A, B):
pass
方法重写
调用父类中的方法:super().xxx():xxx待重写的方法
class Student(Person):
def __init__(self, name, age, number):
super().__init__(name, age)
print('学号是{0}'.format(self.number))
def info(self):
super().info()
print(self.number)
object类
__str__方法:输出内存地址,经常会重写该方法,用以输出对象的描述信息
def __str__(self):
return '我的名字是{0},今年{1}岁'.format(self.name, self.age)
print(stu) # 默认调用__str__方法 : 我的名字是张三,今年20岁
多态的实现
即使不知道一个变量所引用的对象到底是什么类型的,只要想要调用的方法存在,仍然可以通过这个变量调用方法。
如下示例:即使Person没有继承Animal类,但是Person类中有eat方法,便可以进行调用。
class Animal(object):
def eat(self):
print('动物会吃')
class Dog(Animal):
def eat(self):
print('狗吃肉')
class Cat(Animal):
def eat(self):
print('猫吃鱼')
class Person(object):
def eat(self):
print('人吃五谷杂粮')
def fun(animal):
animal.eat()
fun(Dog()) # 狗吃肉
fun(Cat()) # 猫吃鱼
fun(Person()) # 人吃五谷杂粮
特殊属性
特殊属性 | 作用 |
---|---|
_ _ dict _ _ | 获取类对象或实例对象所绑定的所有属性和方法的字典 |
_ _ class _ _ | 获取对象所属的类 |
_ _ bases _ _ | 获取类的父类类型的元素 |
_ _ base _ _ | 获取父类中最近的元素 |
_ _ mro _ _ | 获取类的层次结构 |
_ _ subclasses _ _ | 获取类的子类 |
class A(object):
pass
class B(object):
pass
class C(A, B):
pass
print(x.__dict__) # <class '__main__.C'>
print(C.__dict__) # (<class '__main__.A'>, <class '__main__.B'>)
print(C.__base__) # <class '__main__.A'>
特殊方法
特殊方法 | 作用 |
---|---|
_ _ add _ _ ( ) | a._ _ add _ _(b) 等价于 a+b |
通过重写该方法,可使用自定义对象具有“+”的功能 | |
_ _ len _ _( ) | list1._ _ len_ _ ( ) 等价于 len(list1) |
通过重写该方法,让内置函数len( )的参数可以是自定义类型 | |
_ _ new _ _( ) | 创建对象 |
_ _ init _ _ ( ) | 对创建对象进行初始化 |
class Person:
def __init__(self, name):
self.name = name
def __add__(self, other):
return self.name + other.name
def __len__(self):
return len(self.name)
per1 = Person('JJK')
per2 = Person('Kookie')
per = per1 + per2
print(per) # JJKKookie
print(len(per1)) # 3
class Person(object):
def __new__(cls, *args, **kwargs):
print('__new__被调用执行了,cls的id值为{0}'.format(id(cls))) # 8688
obj = super().__new__(cls)
print('创建的对象的id为:{0}'.format(id(obj))) # 6248
return obj
def __init__(self, name, age):
print('__init__被调用了,self的id值为{0}'.format(id(self))) # 6248
self.name = name
self.age = age
print('object这个类对象的id是{0}'.format(id(object))) # 2600
print('Person这个类对象的id是{0}'.format(id(Person))) # 2600
p1 = Person('张三', 20)
print('p1这个类的实例对象的id是{0}'.format(id(p1))) # 2600
变量的赋值操作、浅拷贝、深拷贝
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk
内存中只有一个实例对象,使用两个变量进行存储;两个变量指向同一个实例对象。
cpu1 = CPU()
cpu2 = cpu1
浅拷贝:copy:只拷贝原对象(类似于快捷方式)(原对象:类的实例对象)
disk = Disk()
computer = Computer(cpu1, disk)
# 浅拷贝
import copy
computer2 = copy.copy(computer)
print(computer, computer.cpu, computer.disk) # CA08 C9C8 C948
print(computer2, computer2.cpu, computer2.disk) # CA48 C9C8 C948
深拷贝:deepcopy:拷贝原对象、子对象
computer3 = copy.deepcopy(computer)
print(computer, computer.cpu, computer.disk) # CA08 C9C8 C948
print(computer3, computer3.cpu, computer3.disk) # CC48 CB88 D3C8
模块
定义
包–模块–类--函数、方法–变量
一个python文件(.py)就是一个模块
导入
import 模块名称 [as 别名]
:import numpy as np
from 模块名称 import 函数/变量/类
:from math import pi
import math
print(math.pow(2, 3)) # 8.0:浮点类型
以主程序形式运行
只有点击运行当前python文件时,才会执行相关操作
if __name__ == '__main__':
# 相关操作
包
分层次的目录结构,将一组功能相近的模块组织在一个目录下
Python Package(包):包含_ _ init _ .py文件
Directory:虽然和python package看上去一样,但是没有 _ init _ _.py文件
from 包名 import 模块名 [as 别名]
import package1.module_A as A
常用模块
模块 | 描述 |
---|---|
sys | 与python解释器及其环境操作相关的标准库 |
time | 与时间相关的各种函数的标准库 |
os | 访问操作系统服务功能的标准库 |
calendar | 与日期相关的各种函数的标准库 |
urllib | 读取来自网上的数据 |
json | 使用json序列化和反序列化对象 |
re | 在字符串中执行正则表达式匹配和替换 |
math | 标准算数运算函数 |
decimal | 精准控制运算精度、有效数位、四舍五入操作的十进制运算 |
logging | 记录事件、错误、警告、调试信息的日志 |
文件
编码格式
python解释器使用Unicode(内存)
python文件默认使用UTF-8编码格式
修改python文件的编码格式:# encoding= gbk
:在文件首行进行修改即可
文件读写
原理:.py文件(打开/新建文件—读/写文件—关闭资源)----解释器----OS----硬盘
语法:file = open(filename [, mode, encoding])
file:被创建的文件对象
filename:要创建/打开的文件名称
mode:打开模式默认只读
encoding:默认文本文件中字符的编写格式为gbk
file = open('a.txt', 'r', encoding='utf-8')
print(file.readlines()) # ['中国\n', '美国\n']
file.close()
若出现:UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 2: illegal multibyte sequence
则应注意file = open('a.txt', 'r', encoding='utf-8')
,是否添加encoding='utf-8'
文件打开
文件类型
文本文件:存储普通字符文本,默认为Unicode字符集
二进制文件:将数据文件用字节进行存储,无法用记事本打开,需用专用软件打开(MP3音频文件…)
打开模式
r:只读模式,文件指针在文件的开头
w:只写模式,文件不存在则创建,文件存在则覆盖原有内容,文件指针在文件开头
a:追加模式,文件不存在则创建,文件存在则在文件末尾追加内容,文件指针在原文件末尾
b:以二进制方式打开文件,需与其他模式共同使用rb,wb
+:以读写方式打开文件,a+
file = open('a.txt', 'w')
file.write('python')
file.close()
文件对象的常用方法
方法 | 描述 |
---|---|
read([size]) | 从文件中读取size个字节或字符的内容返回,若省略size则读取到文件结尾 |
readline() | 从文件中读取一行内容 |
readlines() | 从文件中读取每一行内容作为字符串对象,存入列表 |
write(str) | 把str字符串写入文件 |
writelines(list) | 将字符串列表写入文本文件,不添加换行符 |
seek(offset[, whence]) | 把文件指针移动到新的位置 |
tell() | 返回文件指针当前位置 |
flush() | 把缓冲区内容写入文件,不关闭文件 |
close() | 把缓冲区内容写入文件,同时关闭文件,释放文件相关资源 |
file = open('a.txt', 'r')
print(file.read()) # Jungkook
# Euphoria
print(file.read(2)) #Ju
print(file.readlines()) # ['Jungkook\n', 'Euphoria\n']
file.close()
file = open('a.txt', 'a')
print(file.write('My Time'))
file.close()
file = open('a.txt', 'a')
print(file.writelines(['Begin', '\n', 'Still with you'])) # 想换行需手动添加换行符
file.close()
file = open('a.txt', 'r', encoding='utf-8')
file.seek(3)
print(file.read()) # 国美国:若报错,可考虑file.seek()中offset是否正确
file.close()
file = open('a.txt', 'w')
file.write('hello')
file.flush()
file.write('world')
file.close()
with语句(上下文管理器)
with语句可以自动关闭上下文资源,不论什么原因跳出with块,都可确保文件关闭,不用手动编写close关闭文件。
with open('a.txt', 'r', encoding='utf-8') as file:
print(file.read())
os
os模块
与操作系统有关,对目录或者文件操作
import os
# 调用系统应用程序
os.system('notepad.exe') # 打开记事本
os.system('calc.exe') # 打开计算器
# 调用可执行文件
os.startfile('D:\\Tim\\Bin\\TIM.exe') # 转义字符两个\\
# 获取当前目录
print(os.getcwd())
# 获取目录中的所有文件
print(os.listdir('../pythonProject01'))
# 创建目录
os.mkdir('mypro') # pythonProject01文件夹包含mypro文件夹
# 创建多级目录
os.makedirs('A/B/C') # pythonProject01文件夹包含A文件夹,A文件夹包含B,B包含C
# 删除目录
os.rmdir('mypro')
# 删除多级目录
os.removedirs('A/B/C')
# 修改文件位置
os.chdir('E:\\mainchange')
os.path模块
import os.path
# 获取文件绝对路径
print(os.path.abspath('main.py'))
# 判断文件是否存在
print(os.path.exists('main.py')) # True
# 将文件名和目录名拆分
print(os.path.split('D:\\pythonProject\\pythonProject01\\main.py'))
# 将文件名和扩展名拆分
print(os.path.splitext('main.py'))
# 文件名提取
print(os.path.basename('D:\\pythonProject\\pythonProject01\\main.py')) # main.py
# 目录名提取
print(os.path.dirname('D:\\pythonProject\\pythonProject01\\main.py')) # D:\pythonProject\pythonProject01
os案例
案例1:列出指定目录下的所有python文件
import os
path = os.getcwd()
lis = os.listdir(path)
for filename in lis:
if filename.endswith('.py'):
print(filename)
案例2:列出当前目录下所有文件os.walk(path)
遍历所有目录和文件
import os
path = os.getcwd()
lst = os.walk(path) # 元组形式:当前目录、目录名、文件名
for dirpath, dirname, filename in lst:
for dir in dirname:
print(os.path.join(dirpath, dir))
print('-------------*---------------')
for file in filename:
print(os.path.join(dirpath, file))
print('------------')
pythonProject01文件夹下有.idea和02文件夹、.db和两个python文件,02文件夹下有两个python文件0201.py和0202.py
D:\pythonProject\pythonProject01\.idea
D:\pythonProject\pythonProject01\02
-------------*---------------
D:\pythonProject\pythonProject01\bc_00000LVSQV3ARNLT_05.db
D:\pythonProject\pythonProject01\main.py
D:\pythonProject\pythonProject01\prac02.py
------------
D:\pythonProject\pythonProject01\.idea\inspectionProfiles
-------------*---------------
D:\pythonProject\pythonProject01\.idea\.gitignore
D:\pythonProject\pythonProject01\.idea\misc.xml
D:\pythonProject\pythonProject01\.idea\modules.xml
D:\pythonProject\pythonProject01\.idea\pythonProject01.iml
D:\pythonProject\pythonProject01\.idea\workspace.xml
------------
-------------*---------------
D:\pythonProject\pythonProject01\.idea\inspectionProfiles\profiles_settings.xml
------------
-------------*---------------
D:\pythonProject\pythonProject01\02\0201.py
D:\pythonProject\pythonProject01\02\0202.py
------------
没想到拖着拖着,python基础教程终于结束了,接下来会依据B站视频,编写一个学生信息管理系统,葱葱葱^~^