文章目录
编程思想发展过程
- 面向机器
1.1 机器语言:二进制。通过打开开关,1为打开,0为关闭。
后来发明了打孔机,工作人员不用反复按开关了。
1.2 汇编语言(符号语言):因为机器语言太难编写,发明了汇编。汇编语言亦成为符号语言,因为它使用助记符代替指令或者是操作数的地址,汇编语言提高了可读性,但本质还是面向机器的语言。
- 面向过程
主要是关注具体解决的问题,这就大大减轻了程序员的负担
语言:C语言 Fortran physic
- 结构化设计
随着规模越来越大
第一次软件危机:体现在复杂度上
目前:降低复杂度
- 面向对象
随着硬件发展,随着应用变广泛,随着业务变复杂,变得快速多变
更贴近人类思维,脱离机器思维。但并不说明比面向过程的思维更高级先进,各有优劣,要根据具体情况需求来选择不同的编程方式,或混用
第二次软件危机:体现在可拓展性和可维护性上
语言:python java C++
面向过程 VS 面向对象
面向过程:程序可拓展和可维护性不是很好,加ran_out()函数做了很多修改
面向对象:有方法的重用
类和方法的命名规则
大驼峰:CamelCase
小驼峰:camelCase
一、创建类和实例(instance)
万物都是instance,字符串也是
class Person(object):
pass
class Animal(object):
pass
andy = Person()
jack = Person()
dog = Animal()
cat = Animal()
class Animal(object):
def eat(self, food):
print(f"正在{food}")
def play(self):
print("正在玩耍")
def sleep(self):
print("正在睡觉")
dog = Animal()
dog.eat("狗粮")
dog.play()
dog.sleep()
二、self的作用
在类中代表着一个用这个类创建的对象
class Animal(object):
def eat(self, food):
print(f"正在吃{food}")
def play(self):
print("正在玩耍")
def sleep(self):
self.eat('狗粮') # dog.eat()
print("正在睡觉")
dog = Animal()
dog.sleep()
print("---------------------------------")
Animal.play(dog)
Animal.eat(dog, '狗粮')
正在吃狗粮
正在睡觉
---------------------------------
正在玩耍
正在吃狗粮
三、__init__初始化方法和普通方法
类似于java中的构造方法,给一个对象赋予实例属性
class Animal(object):
def __init__(self, name, age):
"""
__init__初始化方法,在实例化对象的时候,自动调用
"""
self.name = name
self.age = age
def eat(self):
print(f"{self.name}正在吃东西")
def play(self):
print(f"{self.name}正在玩耍")
def sleep(self):
print(f"{self.name}正在睡觉")
三、实例属性和类属性(类变量)
在类中和类外,类属性可以用类直接调用
- 多个实例的实例属性可以共享类属性的值
- 优先查找自身的值,若给实例属性赋值,则和类属性的值断开联系
- 可以动态修改类属性的值
class Animal(object):
# 类属性
age = 5
def eat(self, food):
print(f"{Animal.age}岁的动物正在吃{food}")
def play(self):
print("正在玩耍")
def sleep(self):
print("正在睡觉")
Animal.age = 8 # 也可以动态修改类属性的值
dog = Animal()
dog.age = 10 # 优先查找自身的值
print(f'dog的age是{dog.age}')
pig = Animal()
print(f'pig的age是{pig.age}')
print(f'Animal的age是{Animal.age}') # 类属性可以用类直接调用!!!
dog的age是10
pig的age是8
Animal的age是8
四、类的继承
class Animal(object):
age = 10
def __init__(self, name):
self.name = name
def eat(self):
print(f"{self.name}正在吃东西")
def play(self):
print(f"{self.name}正在玩耍")
def sleep(self):
print(f"{self.name}正在睡觉")
class Dog(Animal):
def bark(self):
print(f"{self.name}会汪汪叫")
class Pig(Animal):
def buu(self):
print(f"小猪会咘咘叫")
dog = Dog("腊肠狗")
dog.eat()
dog.bark()
print(dog.age)
腊肠狗正在吃东西
腊肠狗会汪汪叫
10
五、方法的重写 和 调用父类__init__()初始方法
class Animal(object):
age = 10
def __init__(self, name):
self.name = name
def eat(self):
print(f"{self.name}正在吃东西")
def play(self):
print(f"{self.name}正在玩耍")
def sleep(self):
print(f"{self.name}正在睡觉")
class Dog(Animal):
def __init__(self, name, gender):
super().__init__(name) # self.name = name
self.gender = gender
def eat(self):
print(f"{self.name}正在吃狗粮")
def bark(self):
print(f"{self.name}会汪汪叫")
dog = Dog("腊肠狗", "male")
dog.eat()
腊肠狗正在吃狗粮
综合案例:银行用户系统
import datetime
import prettytable as pt # 将二维数组的打印美化成表格
# 小数点后不能超过2位
def validate(func):
def wrapper(*args, **kwargs):
amount = str(args[1])
# 123.456
index = amount.index(".")
if len(amount) - index - 1 > 2:
print("格式输入错误")
else:
func(*args, **kwargs)
return wrapper
class Bank(object):
account_log = []
def __init__(self, name):
self.name = name
@validate
def deposit(self, account):
user.balance += account
self.write_history(account, "存钱")
@validate
def withdraw(self, account):
if account > user.balance:
print("余额不足")
else:
user.balance -= account
self.write_history(account, "取钱") # 要用self.
def write_history(self, account, type):
# 时间与格式化
d = datetime.datetime.now()
create_time = d.strftime("%Y-%m-%d %H:%M:%S")
if type == "存钱":
money = f"+{account}"
elif type == "取钱":
money = f"-{account}"
l = [self.name, user.name, create_time, type, money, "人民币", user.balance]
Bank.account_log.append(l)
class User(object):
def __init__(self, name, balance):
self.name = name
self.balance = balance
def print_history(self):
# print(Bank.account_log)
# # print(history)
table = pt.PrettyTable()
table.field_names = ["银行名称", "客户", "交易日期", "摘要", "金额", "币种", "余额"] # 设置表格头
# table.align["交易日期"] = "l"
# table.align["摘要"] = "r"
# table.align["币种"] = "l"
for his in Bank.account_log:
table.add_row([his[0], his[1], his[2], his[3], his[4], his[5], his[6]])
print(table)
class BeiJingBank(Bank):
def __init__(self, name):
self.name = name
bank = BeiJingBank("北京工商银行")
user = User("小明", 1000)
def show_menu():
info = '''
操作菜单
0:退出
1:存款
2:取款
3:打印交易信息
'''
print(info)
while True:
show_menu()
number = int(input("请根据菜单编号输入:"))
if number == 0:
print("退出")
break
elif number == 1:
print("存钱")
depositMoney = float(input("请输入要存贮的金额:"))
bank.deposit(depositMoney)
elif number == 2:
print("取钱")
withdrawMoney = float(input("请输入要存贮的金额:"))
bank.withdraw(withdrawMoney)
elif number == 3:
print("查看交易日志")
user.print_history()
else:
print("输入错误")
【拓展】__str__和__repr__的区别
这两个方法是为了更好的看出对象的内容,有利于编程
__ str __:打印对象时,返回名字
__ repr __:交互模式如iPython中输入对象,返回名字。或者 __ str __ 不存在时,打印对象时,返回名字
class Goods(object):
def __init__(self, name, price):
self.name = name
self.price = price
def __str__(self):
return self.name
def __repr__(self):
return f'Good对象:{self.name}'
goods = Goods('apple', 5)
print(goods)
apple
推荐以下这种方法:
class Goods(object):
def __init__(self, name, price):
self.name = name
self.price = price
# def __str__(self):
# return self.name
def __repr__(self):
return f'Good对象:{self.name}'
goods = Goods('apple', 5)
print(goods)
Good对象:apple
【拓展】namedtuple具名元组
from collections import namedtuple
Result = namedtuple('Result', 'status message')
result = Result('ok', '执行成功')
print(result)
Result(status='ok', message='执行成功')