先交代一下上次课留下的作业:
登陆界面
def menu():
#用来显示操作界面
while True:
opt = input("晴选择要进行的操作:\n(1)注册\n(2)登陆\n(3)退出\n")
if opt =="1":
register()
if opt =="2":
denglu()
if opt =="3":
print("Bye~~")
break
这里使用while true很关键,能够让界面跳出去而不是一直在循环
users = []
定义出一个元组,使输出的形式为{'username‘:'','pwd':''}这样
def read_username():
#获取用户输入的用户名
username = input("请输入用户名:\n")
if len(username)<6 or len(username)>9:
print("用户名长度有误")
return read_username()#这就是递归,继续重复这个函数
name_list = [user.get('username')for user in users]
if username in name_list:
print("该用户已存在")
return read_username()
return username
保证录入的用户名是符合要求的
def register():
username = read_username()
pwd = read_pwd()
user = {}
user['username'] = username
user['pwd'] = pwd
users.append(user)#这一步才正式向users里加入了注册信息
print("注册成功")
print(users)
def read_pwd():
pwd1 = input("请输入密码:\n")
if len(pwd1)<6 or len(pwd1)>9:
print("密码长度有误")
return read_pwd()
return pwd1
def find_user_by_name(username):
for user in users:
if user['username'] == username:
return user
return None
def get_user_by_username():
username = input("请输入用户名:\n")
user = find_user_by_name(username)
if user is None:
print("用户不存在")
return get_user_by_username()
return username
用以上两个函数确保登陆时输入的信息跟注册时的一致
def denglu():
username = get_user_by_username()
pwd = input("请输入密码:\n")
print("登陆成功")
dengluchenggong()
def dengluchenggong():
while True:
opt = input("请选择你想进行的操作:\n(1)查看当前用户信息\n(2)查看用户列表\n(3)退出登陆")
if opt == 1:
user_list()
if opt ==2:
denglu()
if opt == 3:
print("再见吧您")
def user_list():
for user in users:
print(user)
menu()
最后一步才是主体,其他都是在定义函数
第二题商品打折,比较好做
products = [{"pname":"笔记本","number":2,'price':2.5},{"pname":"手机","number":1,'price':1800}]
def twozhe(totprice):
print("打两折")
return totprice*(1-0.2)
def threezhe(totprice):
print("打三折")
return totprice*(1-0.3)
def huodong(price,zhekou = None):
if zhekou ==None:
return price
return zhekou(price)
def app():
totnum = sum([item['number'] for item in products])
totprice = sum([item['price']for item in products])
zhekou = None
if totnum>2:
zhekou = twozhe
if totprice>1000:
zhekou = threezhe
price = huodong(totprice,zhekou)
print("总价:%f"%price)
app()
面向对象
面向对象是一种编写代码的思维方式:程序是由什么构成的。
类,其实是一种抽象
User类:把用户相关信息抽象到一起
类名都采用驼峰结构,并且首字母大写
一般来说,类由属性和方法组成,属性表示了类的特点,方法和行为规定了类的功能
程序 = 数据结构(属性)+算法(行为和方法)
函数定义在类里称为方法
类->实例:实例是类的具体化
self指的是:当前对象(方法的调用者),即谁调用这个类就指的是谁
class Cat:
#构造方法,该方法会在创建对象(实例)的时候,自动调用
def __init__(self,color,name):
self.color = color
self.name = name
def catch_rat(self):
print(self.name + "抓到了老鼠")
创建一个实例(对象)
tom = Cat('blue','tom')
tom.catch_rat()
实例化对象的过程:1.分配内存出来(new) 2.初始化值(init)
私有属性
print(tom.name)#tom
tom.name = 'jiafei'
print(tom.name)#jiafei 没有私有化,属性可以被更改
属性私有化
1.用__两个下划线开头,如_name 2.自己约定单下划线
这样属性访问不了,打印会报错,更无法更改
双下划线为什么可以隐藏变量?dict,里面装的实例的所有属性
print(tom.__dict__)#{'color': 'blue', 'name': 'jiafei'}
双下划线开头的属性,会被名称转换:_类名+属性名
class Student:
def __init__(self,name,age):
self.__name = name;
self.__age = age
def set_name(self,name):
if not len(name)<3:
self.__name = name
def get_name(self):
return self.__name
def age(self):
print("年龄")
return self.__age
def set_age(self,age):
if age > 0 and age < 100:
self.__age = age
s = Student("zhangsan",20)
print(s.get_name())#zhangsan
s.set_name("lisi")
print(s.get_name())#lisi 名字被修改
s.age = 40
print(s.age)
类也是对象
self.属性名: 实例属性
在类里直接定义属性,称为类属性,类属性由所有对象共享
class User:
num = 0
def __init__(self,name):
self.name = name
User.num += 1
def print_name(self):
print(self.name,User.num)
@classmethod
def create_user(cls,name,age):
user = cls(name)
user.name = name
user.age = age
return user
u = User("zs")
u.print_name()
u1 = User('1s')
u1.print_name()
User.num += 1
u1.print_name()
u2 = User.create_user('zs',20)
print(u2.age)
print(u2.name)
u3 = u1.create_user('zs',20)
print(u3.age)
#类方法也可以用实例调用
@classmethod 修饰的方法是类方法,类方法可以通过类名调用,类方法必须有一个类型参数:cls
@staticmethod 修饰的是静态方法,通过类名可以访问,当做普通函数就行
继承
python 支持多继承,继承内容与继承顺序相关
所有的类,都会默认继承object类
class A:
def __init__(self):
self.name = 'zs'
def print_test(self):
print("aaaaaaa")
class B:
def __init__(self):
self.name = "ls"
class C(B,A):
def __init__(self):
super().__init__()
self.age = 20
def print_test(self):
super().print_test()
print("ewrewrewr")
c= C()
print(c.name)#zs c继承了A的内容
print(c.age)#20 c仍然有自己的内容
print(C.__mro__)#(<class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
调用属性或方法的查找顺序
c.print_test()
组合优于继承
class D:
def __init__(self):
self.a = A()
def print_test(self):
self.a.print_test()
print("dfdsfdsfsdf")
d = D()
d.print_test()
模拟一个游戏,有一个怪兽(monster),还有一个玩家(hero)
import random as rn
class gghero:
def __init__(self,name):
self.blood = 100
self.power = 12
self.name = name
def attack(self,monster):
minus = rn.randrange(self.power-5,self.power+5)
if monster.has_living():
monster.minus_blood(minus)
print(monster.name + ":" + str(monster.blood))
def minus_blood(self,num):
self.blood-=num
def has_living(self):
if self.blood >0:
return True
return False
当允许使用道具时
m = gghero("哥斯拉")
h = gghero("奥特曼")
while m.has_living() and h.has_living():
m.attack(h)
h.attack(m)
if m.has_living():
print(m.name + "获得胜利")
if h.has_living():
print(h.name + "获得胜利")
class hero(gghero):
def bug_attack(self,monster):
monster.minus_blood(monster.blood)
def attack(self,monster):
super().attack(monster)
num = rn.randint(0,3)
if num == 1:
print(self.name + "使用了道具")
self.bug_attack(monster)
class monster(gghero):
pass
hero = hero("antoman")
monster = monster("gesila")
#m = gghero("哥斯拉")
#h = gghero("奥特曼")
while hero.has_living() and monster.has_living():
hero.attack(monster)
monster.attack(hero)