base
# -*- coding:utf8 -*-
"""
# editor: hjjdreamer
# create-time: 2022/12/4-23:28
# Python-Script: chapter10-class
# describe:
"""
# lesson1
# 面向对象编程
# 设计类class == 设计表格
# 基于类创建对象 == 打印生产表格
# 对象属性赋值 == 填写表格
# 1. 设计一个类 == 类似于生活中设计一张登记表
class Student:
name = None # 记录学生姓名
gender = None # 记录学生性别
nationality = None # 记录国籍
native_place = None # 记录籍贯
age = None # 记录年龄
# 2. 创建一个对象 == 类似于打印生活中的一张登记表
stu_1 = Student() # 即是对象也是变量
# 3. 对象属性进行赋值 == 类似于填报表格
stu_1.name = "as"
stu_1.gender = "male"
stu_1.nationality = "CN"
stu_1.native_place = "ShangDong"
stu_1.age = 31
# 4. 获取对象中的记录信息
print(f"""
{stu_1.name}
{stu_1.gender}
{stu_1.nationality}
{stu_1.native_place}
{stu_1.age}
""")
# lesson2
# class define + use
# 成员使用方法
# self
"""
封装:
类 封装了属性,基于类创建一个个对象来使用
语法:
class <key-words>: ==> 定义了类
class 属性 ==> 定义了类的变量(成员变量)
class 行为 ==> 定义了类的函数(成员方法)
创建类对象的语法
对象 = 类名称()
说函数 == 不在类里面的函数逻辑
说方法 == 在类里面的函数逻辑
"""
"""
在类中定义方法:
留意self
def <func-name>(self ,形参1, ..., 形参N)
方法体
注意:
self (类的内部引用)
1. 必须写,用于成员方法定义
2. 表示类对象自身
3. 类对象调用方法,self会被python自动传入
4. 方法内部,想访问类成员变量,必须使用self
"""
class Student1():
"""
定义一个Student1的类
"""
name = None # 初始化值,为None,是一个容器,装main传入的实参
def say_hi(self): # 定义必须有self
print(f"hello, I am {self.name}, loving you.")
def say_hi2(self, msg2):
print(f"hello, I am {self.name}, loving you and {msg2}.")
stu1 = Student1()
stu1.name = "qwer"
stu1.say_hi() # 调用不能有self
stu2 = Student1()
stu2.name = "rewq"
stu2.say_hi()
stu3 = Student1()
stu3.name = "asdf"
stu3.say_hi2("123456789")
"""
summary:
=======================================
class 类名称:
成员变量
def 成员方法(self, 参数列表):
成员方法体
def 成员方法1(self):
成员方法体1
对象 = 类名称()
对象.成员方法(实参)
对象.成员方法1()
attention:
只用通过self, 成员方法才能访问类的成员变量
self出现在形参中,但不占用参数位置,无需理会
"""
# lesson3 类与对象
"""
对象名 = 类名称
类只是一种程序内的设计图纸,需要基于图纸生产实体(对象),才能正常工作
"""
class Clock: # 可以没有括号,因为没有参数
"""
定义闹钟模板
"""
id = None
price = None
def ring(self):
import winsound
# 闹钟声音刺耳
winsound.Beep(37, 300)
clock1 = Clock()
clock1.id = "001206"
clock1.price = 20.00
# 输出的是闹钟001206实体的信息
print(f"clock1_id == {clock1.id}, clock1_price == {clock1.price}")
clock1.ring()
clock2 = Clock()
clock2.id = "001205"
clock2.price = 20.00
# 输出的是闹钟001206实体的信息
print(f"clock1_id == {clock2.id}, clock1_price == {clock2.price}")
clock2.ring()
"""
思想:
事物 = 属性 + 行为
类 == 设计图纸
对象 == 具体实体
面向对象编程:
使用对象进行编程
设计类 ==> 基于类创建对象 ==> 使用对象完成具体工作
"""
# lesson4: 构造方法
"""
构造方法向成员变量赋值
以传参的形式将成员变量的值给传进去
__init__() == 构造方法
功能:
1. 创建类对象时候,会自动执行
2. 创建类对象时候,将传入参数自动传递给__init__方法使用
"""
class Student2:
name = None # 假如相关属性没有在这里定义,
age = None # 则会在__init__方法下完成定义+赋值
tel = None
def __init__(self, name, age, tel): # 类似与形参的功能
self.name = name # 定义类的属性name = 外部传参的属性name
self.age = age # 构造方法内定义成员变量,需要使用self关键字
self.tel = tel
print("student2 create success")
stu4 = Student2("ZXC", 32, "13465798782")
print(f"name == {stu4.name}")
print(f"age == {stu4.age}")
print(f"tel == {stu4.tel}")
"""
attention:
__init__(self)
1. 2条下划线__
2. self不能省略
"""
# lesson5 魔术方法
"""
__init__ == 构造方法
__str__ == 字符串方法 == 控制类转换为字符串的行为
运算符重载
__lt__ == 小于符号比较
__le__ == 小于等于,大于等于符号比较
__eq__ == ==符号比较
"""
class Student4:
def __init__(self, name, age):
self.name = name
self.age = age
# __str__(self)
def __str__(self):
return f"Student4 == class, class name = {self.name} + age = {self.age}"
# __lt__(self)
def __lt__(self, other): # F # 2个对象。other表示另外一个
return self.age < other.age # T # Bool + 不能带上等于号
# __le__(self) 比较的是内存地址
def __le__(self, other):
return self.age <= other.age
# __eq__(self)
def __eq__(self, other):
return self.age == other.age
stu6 = Student4("cvb", 62)
stu7 = Student4("cvb", 62)
stu5 = Student4("ewr", 45)
print(stu5) # <__main__.Student4 object at 0x0000023090D04E80>
print(str(stu5)) # <__main__.Student4 object at 0x0000023090D04E80>
# Student4 == class, class name = ewr + age = 45
# Student4 == class, class name = ewr + age = 45
# __lt__
print(stu5 > stu6)
print(stu5 < stu6)
# __le__
print(stu5 <= stu6)
print(stu5 >= stu6)
print(stu6 == stu7) # F --> T
# __eq__
print(stu5 == stu6)
print(stu6 == stu7)
# lesson6 封装 + 私有成员
"""
面向对象编程:
基于模板(类),去创建实体(对象),使用对象完成功能开发
私有成员
现实世界有不公开的属性与行为,那么作为现实事物在程序中映射的类,也应该支持
类中使用私有成员的形式来支持程序中不公开的属性与行为
1. 私有成员变量 ==> 定义:变量名以"__"开头
2. 私有成员方法 ==> 定义:变量名以"__"开头
私有成员能被类的其他成员属性+方法调用,外部不能使用
在类中提供仅供内部使用的属性和方法,而不对外公开(类对象无法使用)
"""
class Phone():
# 私有成员变量
__current_voltage = 0.5 # 当前手机运行电压
# 私有成员方法
def __keep_single_core(self): # 定义手机以单核运行
print("CPU以单核模式运行")
# phone1 = Phone()
# phone1.keep_single_core()
# Traceback (most recent call last):
# File "E:/python/ithelma/chapter10-class.py", line 277, in <module>
# phone1.keep_single_core()
# AttributeError: 'Phone' object has no attribute 'keep_single_core'
# 私有成员能被类的其他属性 + 方法调用,外部不能使用
def call_by_5g(self):
if self.__current_voltage >= 1:
print("5G calling is ok")
else:
self.__keep_single_core()
print("ele is lower, can not use 5g, keep_single_core to safe")
phone2 = Phone()
# __current_voltage = 1
phone2.call_by_5g()
# __current_voltage = 0.2
phone2 = Phone()
phone2.call_by_5g()
# lesson7: Example
class Phone1:
# 提供私有成员变量
__is_5g_enable = False
# 提供私有成员方法:__check_5g()
def __check_5g(self):
if self.__is_5g_enable:
print("5g开启")
else:
print("5g close")
# 提供公开成员方法:call_by_5g()
def call_by_5g(self):
self.__check_5g()
print("running")
phone3 = Phone1()
phone3.call_by_5g()
polymorphism
# -*- coding:utf8 -*-
"""
# editor: hjjdreamer
# create-time: 2022/12/11-10:45
# Python-Script: chapter10-class-polymorphism.py
# describe:
多态
多种状态 == 完成某个行为时候,使用不同的对象会得到不同的状态
== 同一个行为,使用不同对象获得不同的状态
定义函数,通过类型注释声明需要父类对象,
实际传入子类对象进行工作
从而:获得不同的工作状态
"""
class Animal:
Animal = None
def speak(self):
pass # 空实现
class Dog(Animal):
Animal = "DOG"
def speak(self):
print("wang~~~~")
class Cat(Animal):
Animal = "CAT"
def speak(self):
print("miao~~~~")
def make_noise(animal: Animal):
print(animal.Animal)
animal.speak()
dog1 = Dog()
cat1 = Cat()
make_noise(dog1)
make_noise(cat1)
"""
同样的行为(函数),传入不同的对象,得到不同的状态
父类定义声明 == 函数/方法/声明在父类对象接收
子类执行函数 == 实际传入父类的子类对象进行工作
结果 == 获得同一行为的不同状态
"""
"""
父类用来决定有哪些方法
具体的方法实现:由子类自行决定
这种写法:抽象类 == 接口 == 包含抽象方法的类叫抽象类
含有抽象方法的类称为抽象类
抽象方法:方法体是空实现的pass称之为抽象方法
"""
# 父类定义顶层设计 == 抽象类
"""
抽象类 == 顶层设计,对子类的软性约束,要求子类必须复写父类的一些方法
"""
class AC:
def cool_wind(self):
"""cold"""
pass
def hot_wind(self):
"""hot"""
pass
def swing_l_r(self):
"""swing"""
pass
# 子类根据抽象类定义具体对象执行类功能
"""
子类做具体实现
"""
class Midea_AC(AC):
def cool_wind(self):
print("midea-cool")
def hot_wind(self):
"""hot"""
print("midea-hot")
def swing_l_r(self):
"swing"
print("midea-swing")
class GREE_AC(AC):
def cool_wind(self):
print("GREE-cool")
def hot_wind(self):
"""hot"""
print("GREE-hot")
def swing_l_r(self):
"swing"
print("GREE-swing")
# 定义方法调用 == 如何调用
def make_cool(ac: AC):
ac.cool_wind()
# 创建类对象
midea_ac1 = Midea_AC()
gree_ac1 = GREE_AC()
# 调用方法
make_cool(midea_ac1)
make_cool(gree_ac1)
inherit
# -*- coding:utf8 -*-
"""
# editor: hjjdreamer
# create-time: 2022/12/11-9:57
# Python-Script: chapter10-class-TypeAnnotation.py.py
# describe:
演示变量的类型注解
"""
# 基础数据类型注解
import json
from typing import List, Tuple, Dict
import random
var_1: int = 10
var_2: str = "asdadaffa"
var_3: bool = False
# 类对象类型注解
class Student:
pass
stu: Student = Student()
# 基础容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_dict: dict = {"da": 456}
# 容器类型详细注解
my_list: List[int] = [1, 2, 3]
my_tuple: Tuple[int, str, bool] = (1, "eeq", True)
my_dict: Dict[str, int] = {"da": 456}
# 在注释中进行类型注解
var_12 = random.randint(1, 10) # type: int
var_22 = json.loads('{"name": "dadasdfa"}') # type: dict[str,str]
def func1():
return 10
var_32 = func1() # type: int
# 函数方法的类型注解
# 1.形参的类型注解
def add(x: int, y: int):
return x + y
print(add(1, 2.3))
# 对返回值进行类型注解
def func(data: list) -> list:
return data
print(func(1))
# Union
from typing import Union
my_list1: List[Union[int, str]] = [1, 2, "dfas", "asdff"]
def func1(data: Union[int, str]) -> Union[int, str]:
pass
func()
example
data
# -*- coding:utf8 -*-
"""
# editor: hjjdreamer
# create-time: 2022/12/12-8:08
# Python-Script: data_define.py
# describe:
"""
# 数据定义类
class Record:
def __init__(self, date, order_id, money, province):
# 在构建方法__init__内定义变量更好,如下
self.date = date # 订单日期
self.order_id = order_id # 订单ID
self.money = money # 订单金额
self.province = province # 销售省份
def __str__(self):
return f"{self.date}, {self.order_id}, {self.money}, {self.province}"
file
# -*- coding:utf8 -*-
"""
# editor: hjjdreamer
# create-time: 2022/12/12-8:16
# Python-Script: file_define.py
# describe:
"""
from data_define import Record
from typing import List, Tuple, Dict
import json
# 抽象类 == 确定顶层设计, 确定有哪些功能需要实现
class FileReader:
def read_data(self) -> List[Record]:
"""
读取文件数据,读到每一条数据转换为Record对象
封装为list进行返回
"""
pass
class TextFileReader(FileReader):
def __init__(self, path):
self.path = path # 定义成员变量记录文件路径
# 复写(实现抽象方法)父类方法
def read_data(self) -> List[Record]:
f = open(self.path, "r", encoding="UTF-8")
record_list: List[Record] = []
for line in f.readlines():
# 测试输出结果
# print(line)
line = line.strip() # 换行符进行处理 == 删除\n
# 测试输出结果
# print(line)
data_list = line.split(",") # 定义分隔符
# 测试输出结果
# print(line)
record = Record(data_list[0], data_list[1], int(data_list[2]), data_list[3])
record_list.append(record)
f.close()
return record_list
class JsonFileReader(FileReader):
def __init__(self, path):
self.path = path # 定义成员变量记录文件路径
# 复写(实现抽象方法)父类方法
def read_data(self) -> List[Record]:
f = open(self.path, "r", encoding="UTF-8")
record_list: List[Record] = []
for line in f.readlines():
data_dict = json.loads(line)
record = Record(data_dict["date"], data_dict["order_id"], int(data_dict["money"]), data_dict["province"])
record_list.append(record)
f.close()
return record_list
if __name__ == "__main__":
text_file_reader = TextFileReader("../data/201101_sale.txt")
json_file_reader = JsonFileReader("../data/201102_salejson.txt")
list1 = text_file_reader.read_data()
list2 = json_file_reader.read_data()
for l in list1:
print(l)
for l in list2:
print(l)
main
# -*- coding:utf8 -*-
"""
# editor: hjjdreamer
# create-time: 2022/12/12-12:51
# Python-Script: main.py
# describe:
"""
from typing import List
from file_define import FileReader, JsonFileReader, TextFileReader
from data_define import Record
test_file_reader = TextFileReader("../data/201101_sale.txt")
json_file_reader = JsonFileReader("../data/201102_salejson.txt")
jan_data: List[Record] = test_file_reader.read_data()
feb_data: List[Record] = json_file_reader.read_data()
# 将2个月的数据合并为一个list来存储
all_data: List[Record] = jan_data + feb_data
# 进行数据计算
data_dict = {}
for record in all_data:
if record.date in data_dict.keys():
# 当前日期已经有记录了,所以和老记录做数据累计即可
data_dict[record.date] += record.money
else:
# 没有新纪录就进行赋值操作
data_dict[record.date] = record.money
print(data_dict)
# {'2011-01-31': 29250, '2011-02-01': 14448}