2019-05-25第五次课

上期作业总结:

1、使用字典表示用户对象,例如:[{‘name’:'zhangsan','pwd':'123456',hasLogin:false}],将字典放入list中来表示数据库,请完成用户 注册、登录功能用户信息。
(1)注册
(2)登录
(3)查看
(4) 退出登录


#info以存储字典的列表的数据结构表示已有的账户信息
info = [{'name':'zhangsan','pwd':'123456','hasLogin':False},
        {'name':'lisi','pwd':'123456','hasLogin':False},
        {'name':'wangwu','pwd':'123456','hasLogin':False},
        ]

#以下三个函数用于对info的增、查、改
def get_info(n = "*",f = '*'):
    """
    查看某一个用户的某个信息
    :param n: 用户姓名,未指明则打印全部信息
    :param f: info该用户某一个value,未指明则全输出
    :return: 'Print' or 'error' or value or dict
    """
    if n == '*':

        for x in info:
            print(x)
        return 'Print'
    for x in info:
        if n == x['name']:
            if f == '*':
                return x
            return x[f]
    return 'error'


def set_info(n,p):
    """
    向info插入一个字典
    :param n: 该字典‘name’的value
    :param p: 该字典‘pwd’的value
    :return: ‘ok’
    """
    new_info = {'name':n,'pwd':p,'hasLogin':False}
    info.append(new_info)
    return 'ok'


def Refresh(n,s):
    """
    刷新登陆状态
    :param n:账户姓名
    :param s: 刷新的登陆状态,True,False
    :return:‘ok’
    """
    for x in info:
        if n == x["name"]:
            x['hasLogin'] = s
            return "ok"

#以下两个函数用于实现登陆功能
def chack_login():
    """
    检查登陆信息是否正确
    :return: '0',name
    """
    name = input("请输入名字:(输入'0'返回上一菜单)")
    if name == '0':
        return '0'

    if get_info(name, 'pwd') == 'error':
        print("无效的名字,请重试")
        return chack_login()

    pwd = input("请输入密码:")
    if pwd != get_info(name, 'pwd'):
        print("密码错误,请重试")
        return chack_login()

    else:
        print("密码正确")
        return name


def login_in():
    """
    该函数实现登陆功能
    :return: 'exit' or login_name
    """
    login_name = chack_login()
    if login_name == '0':
        return 'exit'
    else:
        Refresh(login_name, True)
        return login_name

#以下函数用于实现查看信息界面功能
def menu_info(account_info):
    """
    查看信息界面
    :param account_info:账户名称
    :return: 'exit'
    """
    while True :
        print("您现在登陆的账户为%s" % (account_info))
        print("请选择接下来要查看的信息:")
        select = input("1.查看当前用户信息\n 2.查看所有用户信息\n 3.退出登陆")
        select = int(select)
        if select == 1:
            print(get_info(account_info))
        elif select == 2:
            get_info()
        elif select == 3:
            Refresh(account_info, False)
            return 'exit'
        else:
            print('您输入了无效的操作')

#以下三个函数与注册功能相关
def get_username():
    """
    检查注册的用户名是否合法
    :return: '0' or new_name
    """
    user_name = input("请输入要创建的账户名:(输入'0'返回上一菜单)\n (要求:长度应在3到12位)")
    if user_name == '0':
        return '0'
    if len(user_name) < 3 or len(user_name) >12:
        print("用户名长度不合法")
        return get_username()
    if get_info(user_name) == 'error':
        return user_name
    else:
        print("该账户已存在")
        return get_username()


def get_pwd():
    """
    检查注册的密码是否合法
    :return: user_pwd
    """
    user_pwd = input("请输入创建账户的密码:(要求:长度至少6位,但不超过20位)")
    if len(user_pwd) < 6 or len(user_pwd) >20:
        print("密码长度不合法")
        return get_pwd()
    else:
        return user_pwd


def register():
    """
    该函数实现注册界面的相关操作
    :return:'exit'
    """
    new_name = get_username()
    if  new_name == '0':
        return 'exit'
    else:
        new_pwd = get_pwd()
        if set_info(new_name, new_pwd) == 'ok':
            print("恭喜你!注册成功。")
            return 'exit'
        else:
            print("出现了系统错误,写入函数返回值出错")
            return 'exit'

#以下函数用于实现主菜单功能
def menu_start():
    """
    实现初始菜单的功能
    :return: 'exit'
    """
    while True:

        select = input("请选择要进行的操作:\n (1)登陆\n (2)注册\n (3)退出\n")
        select = int(select)
        if select == 1:
            result = login_in()
            if result == 'exit':
                continue
            else:
                menu_info(result)
        elif select == 2:
            register()
        elif select == 3:
            break
        else:
            print('无效操作,请重试')
    return 'exit'


#主函数部分:
if menu_start() == 'exit':
    print('退出成功')



2、模拟用户下单过程,当用户买的物品超过3件时,给与2折优惠(优先级较高)。当用户总价超过100元给与3折优惠。(高阶函数)[{“pname”:"","price":"","number":12}]

# -*- coding: utf-8 -*-
# @Time    : 19-5-24 上午10:27
# @Author  : Jingtao Yu
# @Email   : 2463038861@qq.com
# @File    : test4.5.py
# @Software: PyCharm

order = [{'pname':'note','price':8,'number':1},
         {'pname':'apple','price':2,'number':5},
         {'pname':'computer','price':4000,'number':1}]


def discount1(price):
    """
    打二折
    :param price:总价
    :return: 折扣后价格
    """
    return price * 0.2


def discount2(price):
    """
    打三折
    :param price:总价
    :return: 折扣后价格
    """
    return price * 0.3


def calulate(price,strategy):
    """
    根据不同的策略进行不同的折扣计算
    :param price: 总价
    :param strategy: 策略
    :return: strategy(price)
    """
    if strategy == None:
        return price
    return strategy(price)


def discount(orders):
    """
    根据优惠政策给予相应折扣后的价格
    :param order: 订单列表
    :return: 折扣后的价格
    """
    pnum = sum([item['number'] for item in orders])
    pprice = sum([item['price']*item['number'] for item in orders])
    strategy = None

    if pnum >= 3:
        strategy = discount1
    elif pprice >= 1000:
        strategy = discount2
    return calulate(pprice,strategy)



print('折扣后,你要付的金额为:',end = '')
print(discount(order))



面向对象

面向对象是一种编写代码的思维方式:程序是由什么构成的

  1. 类:其实是一种抽象。
  2. User类:把用户相关信息抽象到一起。
  3. 函数命名用下划线表示法,类名用驼峰结构,并把首字母大写。
  4. 一般来说,类由属性和(方法)行为组成,属性表示了这个类的特点,(方法)行为规定了这个类的功能。
  5. 程序(类) = 数据结构(属性) + 算法(方法、行为)
  6. 函数定义在类里的时候,成为方法。
  7. 类->实例:实例是类的具体化。
class Cat:
    #构造方法,该方法会在创建对象(实例)的时候,自动调用
    #分配内存:一般不考虑

    #初始化值
    def __init__(self,color,name):
        self.color = color
        self.name = name

    # self指的是:当前对象(当前方法的调用者)
    def catch_rat(self):
        print(self.name + "抓到了老鼠")


#创建一个实例
tom = Cat('Blue','Tom')
tom.catch_rat()

#私有属性
print(tom.name)
tom.name = 'Garfield'
print(tom.name)

实例化对象的过程:1,分配内存出来(方法:new) 2,初始化值(方法:init)

  • 私有属性

属性私有化:
1,两个下划线开头
2,自行约定,单下划线开头

  • 双下划线为什么能够隐藏变量?

通过duct可查到,里面装的实例的所有属性。双下划线开头的属性,会被名称转换:_类名+属性名

  • 语法糖
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

    #语法糖:简化了调用
    @property
    def age(self):
        print("年龄:",end = '')
        return  self.__age

    @age.setter
    def age(self,age):
        if age > 0 and age < 100:
            self.__age = age

s = Student("zhangsan",20)

#提供了get、set方法
print(s.get_name())
s.set_name("lisi")
print(s.get_name())
#语法糖,让调用类方法的更简单、方便
s.age = 50
print(s.age)

类本身也是对象
类的所有属性存在一个字典里

class User:
    #在类里直接定义的属性,称为类属性,类属性由所有对象共享
    num = 0

    def __init__(self,name):
        # self.属性名:实例属性
        self.name = name
        User.num += 1

    #使用print(对象)时,后自动调用该函数
    def __str__(self):
        str = ''
        return str

    def print_name(self):
        print(self.name,User.num)

语法糖: @classmethod, @staticmethod

    #定义一个类方法,类和实例皆可调用,建议通过类名来调用,该方法必须有一个类型参数“cls”
    @classmethod
    def create_user(cls,name,age):
        #输出了该类的类型
        print(cls)
        user = cls(name)
        user.age = age
        return user

    #静态方法:效果与普通函数类似,通过类名来访问(工具类),调用方式同类方法
    @staticmethod
    def sum(a,b):
        return a + b


u = User("zs")
u.print_name()

u1 = User("ls")
u1.print_name()

User.num += 1

u1.print_name()

u2 = User.create_user('ZS',20)
print(u2.age)
print(u2.name)

print(User.sum(2,3))

案例

模拟一个游戏,有一个怪兽(Monster),还有一个玩家(Hero)

import random as rn

class Sprite:

    def __init__(self,name):
        self.blood = 100
        self.power = 12
        self.name = name

    def attack(self,Enemy):
        minus = rn.randrange(self.power - 5,self.power + 5)
        if Enemy.has_living():
            Enemy.minus_blood(minus)
        print(Enemy.name + ":" + str(Enemy.blood))

    def minus_blood(self,num):
        self.blood -= num

    def has_living(self):
        if self.blood > 0:
            return True
        return False

class Hero(Sprite):

    def bug_attack(self,Enemy):
        Enemy.minus_blood(Enemy.blood)

    def attack(self,Enemy):
        super().attack(Enemy)
        num = rn.randint(0,3)
        if num == 1:
            print(self.name + "使用了道具")
            self.bug_attack(Enemy)

m = Sprite("monster")
n = Hero("hero")

while m.has_living() and n.has_living():
    m.attack(n)
    n.attack(m)

if m.has_living():
    print("Monster Win")
elif n.has_living():
    print("Hero Win")
else:
    print("No Winer")
  • 单例模式:

让该类只存在一个实例,多个对象也只调用一个实例。


class S:
    instance = None
    #__new__用来制作单例
    def __new__(cls, *args, **kwargs):
        if S.instance is None:
            S.instance = super().__new__(cls)

        return S.instance

s1 = S()
print(id(s1))
s2 = S()
print(id(s2))

继承

所有的类,都会默认继承Object类

class A:
    def __init__(self):
        self.name = 'A'

    def print_test(self):
        print("AAAAAAAAAA")

class B:
    def __init__(self):
        self.name = 'B'

class C(A):
    def __init__(self):
        #继承父类的属性
        super().__init__()
        self.age = 20


    def print_test(self):
        #继承父类的方法
        super().print_test()
        print("BBBBBBBB")


#python支持多继承,继承内容与继承顺序相关
class D(B,A):
    pass


c = C()
print(c.name)
print(c.age)
c.print_test()

d = D()
print(d.name)
#类中查找属性或方法的搜索顺序,输出了多继承时类的搜索顺序
print(C.__mro__)


#继承需谨慎,组合优于继承
class F:
    def __init__(self):
        self.a = A()

    def print_test(self):
        self.a.print_test()
        print("FFFFFFFFFF")

f = F()
f.print_test()

子类沿袭父类的属性和方法,也可以在此之上扩充

  • 鸭子类型

鸭子类型:没有共同继承的两个类,但功能类似或相同,被称为鸭子类型
“叫起来像鸭子,走起来像鸭子,就是鸭子”

  • 子类的对象也是父类的实例

print(isinstance(c,B))#c是否为B的实例
print(issubclass(B,A))#B是否为A的子类

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容