super封装property反射

作业讲解

两种登录注册的方式

方式一:先登录,登录成功后创建实例化对象

 1  import os
 2  def login(name,passwd,filepath = 'userinfo'):
 3      with open(filepath,encoding='utf-8') as f:
 4          for line in f:
 5              user,pwd = line.strip().split('|')
 6              if user == name and passwd == pwd:
 7                  return True
 8          else:
 9              return False
10 11  class User:
12      def __init__(self,username,password):
13          self.user = username
14          self.pwd = password
15      def change_pwd(self):
16          oldpwd = input('输入原密码 :')
17          newpwd = input('输入新密码 :')
18          flag = False
19          with open('userinfo',encoding='utf-8') as f1,open('userinfo.bak',mode='w',encoding='utf-8') as f2:
20              for line in f1:
21                  username,password = line.strip().split('|')
22                  if username == self.user and password == oldpwd:
23                      line = '%s|%s\n'%(username,newpwd)
24                      flag = True
25                  f2.write(line)
26          os.remove('userinfo')
27          os.rename('userinfo.bak','userinfo')
28          return flag
29  name = input('user : ')
30  passwd = input('pwd : ')
31  ret = login(name,passwd)
32  if ret:
33      print('登录成功')
34      obj = User(name,passwd)
35      res = obj.change_pwd()
36      if res:print('修改成功')

 

方式二:先注册,注册时直接创建实例化对象,登录时与实例化对象比较

 1  # class User:
 2  #     def __init__(self, name, pwd):
 3  #         self.name = name
 4  #         self.pwd = pwd
 5  #
 6  # class Account:
 7  #     def __init__(self):
 8  #         # 用户列表,数据格式:[user对象,user对象,user对象]
 9  #         self.user_list = []
10  #
11  #     def login(self):
12  #         # 登录
13  #         # 登录 输入用户名密码
14  #         # 和self.user_list作比对
15  #         username = input('用户名 :')
16  #         password = input('密  码 :')
17  #         for user in self.user_list:
18  #             if username == user.name and password == user.pwd:
19  #                 print('登录成功')
20  #                 break
21  #         else:
22  #             print('登录失败')
23  #
24  #     def register(self,name,pwd):
25  #         if self.user_list:
26  #             for i in self.user_list:
27  #                 if i.name == name:
28  #                     print('用户名已被使用!')
29  #                     break
30  #             else:
31  #                 self.user_list.append(User(name,pwd))
32  #                 print('添加成功!')
33  #         else:
34  #             self.user_list.append(User(name, pwd))
35  #             print('添加成功!')
36  #
37  #     def run(self):
38  #         opt_lst= ['登录','注册']
39  #         while True:
40  #             for index,item in enumerate(opt_lst,1):
41  #                 print(index,item)
42  #             num = input('请输入您需要的操作序号 :').strip()
43  #             if num == '1':
44  #                 self.login()
45  #             elif num == '2':
46  #                 self.register()
47  #             elif num.upper() == 'Q':
48  #                 break
49  #
50  # if __name__ == '__main__':
51  #     obj = Account()
52  #     obj.run()

 

注意:run部分的用处及代码

今日内容

super

  1. 什么是super方法?

    按照mro顺序来寻找当前类的下一个类

     1  class A(object):
     2      def func(self):
     3          print('A')
     4  class B(A):
     5      def func(self):
     6          super().func()
     7          print('B')
     8  class C(A):
     9      def func(self):
    10          super().func()
    11          print('C')
    12  class D(B,C):
    13      def func(self):
    14          super().func()
    15          super(D,self).func()
    16          print('D')
    17  D().func() # ACBD  但打印出来是反顺序

     

  2. super在py3与py2中使用方法不一样

    1. 在py3中:不是必须传参数,自动就帮我们寻找当前类的mro顺序的下一个类中的同名方法

    2. 在py2中:新式类中,需要我们主动传递参数super(子类的名字,子类的对象).函数名(),这样才能够帮我们调用到这个子类的mro顺序的下一个类中的方法(为什么不说经典类?因为经典类只有深度优先)

  3. 在单继承中执行父类的同名方法

    在D类中找super的func,那么可以这样写 super().func()

    也可以这样写 super(D,self).func() (并且在py2的新式类中必须这样写)

     1  class User:
     2      def __init__(self,name):
     3          self.name = name
     4  class VIPUser(User):
     5      def __init__(self,name,level,strat_date,end_date):
     6          # User.__init__(self,name)          # 原始的
     7          super().__init__(name)              # 推荐的
     8          # super(VIPUser,self).__init__(name)# py2用的
     9          self.level = level
    10          self.strat_date = strat_date
    11          self.end_date = end_date
    12 13  太白 = VIPUser('太白',6,'2019-01-01','2020-01-01')
    14  print(太白.__dict__)

     

封装

  1. 广义上的封装:把属性和方法装起来,外面不能直接调用了,要通过类的名字来调用

  2. 狭义上的封装:把属性和方法藏起来,外面不能调用,只能在内部偷偷调用(私有)

    1  # class User:
    2  #     def __init__(self,name,passwd):
    3  #         self.usr = name
    4  #         self.__pwd = passwd  # 私有的实例变量/私有的对象属性
    5  # alex = User('alex','sbsbsb')
    6  # print(alex.__pwd)  # 报错
    7  # print(alex.pwd)    # 报错

     

    给一个名字前面加上了双下划线的时候,这个名字就变成了一个私有的所有的私有的内容或者名字都不能在类的外部调用,只能在类的内部使用了

  3. 使用私有有三种情况

    1. 不想让你看也不想让你改

    2. 可以让你看,但不让你改

    3. 可以看也可以改,但是要求你按照我的规则改

      1  # class User:
      2  #     def __init__(self,name,passwd):
      3  #         self.usr = name
      4  #         self.__pwd = passwd  # 私有的实例变量/私有的对象属性
      5  #     def get_pwd(self):       # 表示的是用户不能改只能看,这里我们定义一个get方法实现的
      6  #         return self.__pwd
      7  #     def change_pwd(self):    # 表示用户必须调用我们自定义的修改方式来进行变量的修改,这里我们用change方法实现
      8  #         pass

       

  4. 封装的语法

    1. 私有的静态变量

    2. 私有的实例变量

    3. 私有的绑定方法

      1  # class User:
      2  #     __Country = 'China'   # 私有的静态变量
      3  #     def func(self):
      4  #         print(User.__Country)  # 在类的内部可以调用
      5  # print(User.Country)  # 报错 在类的外部不能调用
      6  # print(User.__Country)# 报错 在类的外部不能调用
      7  # User().func()

       

       1  # import  hashlib
       2  # class User:
       3  #     def __init__(self,name,passwd):
       4  #         self.usr = name
       5  #         self.__pwd = passwd  # 私有的实例变量
       6  #     def __get_md5(self):     # 私有的绑定方法
       7  #         md5 = hashlib.md5(self.usr.encode('utf-8'))
       8  #         md5.update(self.__pwd.encode('utf-8'))
       9  #         return md5.hexdigest()
      10  #     def getpwd(self):
      11  #         return self.__get_md5()
      12  # alex = User('alex','sbsbsb')
      13  # print(alex.getpwd())

       

  5. 私有的特点

    1. 可以在类的内部使用

    2. 不可以在类的外部使用

    3. 类的子类中也不能使用

      1  # class Foo(object):
      2  #     def __func(self):
      3  #         print('in Foo')
      4  # class Son(Foo):
      5  #     def __init__(self):
      6  #         self.__func()
      7  # Son()

       

  6. 封装的原理

    变形,在哪里变形?

    在类的内部使用的时候,自动的把当前这句话所在的类的名字拼在私有变量前完成变形

     1  # class User:
     2  #     __Country = 'China'   # 私有的静态变量
     3  #     __Role = '法师'   # 私有的静态变量
     4  #     def func(self):
     5  #         print(self.__Country)  # 在类的内部使用的时候,自动的把当前这句话所在的类的名字拼在私有变量前完成变形
     6  # print(User._User__Country)
     7  # print(User._User__Role)
     8  # __Country -->'_User__Country': 'China'
     9  # __Role    -->'_User__Role': '法师'
    10  # User.__aaa = 'bbb'  # 在类的外部根本不能定义私有的概念

     

  7. 类中变量的三个级别

    • 公有的public:类内外都能用,父类子类都可以用

    • 保护的protect:类内可以用,父类子类都可以用,类外不能用

    • 私有的private:本类的类内部能用,其他地方都不能用

    python只支持公有的私有的

类中的三个装饰器

property
  1. 作用是什么?

    1. 把一个方法伪装成一个属性,在调用这个方法的时候不需要加()就可以直接得到返回值

       1  # import time
       2  # class Person:
       3  #     def __init__(self,name,birth):
       4  #         self.name = name
       5  #         self.birth = birth
       6  #     @property
       7  #     def age(self):   # 装饰的这个方法 不能有参数
       8  #         return time.localtime().tm_year - self.birth
       9  #
      10  # 太白 = Person('太白',1998)
      11  # print(太白.age)

       

    2. 和私有的属性合作

       1  # class User:
       2  #     def __init__(self,usr,pwd):
       3  #         self.usr = usr
       4  #         self.__pwd = pwd
       5  #     @property
       6  #     def pwd(self):
       7  #         return self.__pwd
       8  #
       9  # alex = User('alex','sbsbsb')
      10  # print(alex.pwd)
       1 # class Goods:
       2  #     discount = 0.8
       3  #     def __init__(self,name,origin_price):
       4  #         self.name = name
       5  #         self.__price = origin_price
       6  #     @property
       7  #     def price(self):
       8  #         return self.__price * self.discount
       9  #
      10  # apple = Goods('apple',5)
      11  # print(apple.price)

       

    3. property进阶:改变私有属性(用的时候必须有property修饰的同名方法)

       1  # class Goods:
       2  #     discount = 0.8
       3  #     def __init__(self,name,origin_price):
       4  #         self.name = name
       5  #         self.__price = origin_price
       6  #     @property
       7  #     def price(self):
       8  #         return self.__price * self.discount
       9  #
      10  #     @price.setter
      11  #     def price(self,new_value):
      12  #         if isinstance(new_value,int):
      13  #             self.__price = new_value
      14  #
      15  # apple = Goods('apple',5)
      16  # print(apple.price)   # 调用的是被@property装饰的price
      17  # apple.price = 10     # 调用的是被setter装饰的price
      18  # print(apple.price)

       

       1  class Goods:
       2      discount = 0.8
       3      def __init__(self,name,origin_price):
       4          self.name = name
       5          self.__price = origin_price
       6      @property
       7      def price(self):
       8          return self.__price * self.discount
       9 10      @price.setter
      11      def price(self,new_value):
      12          if isinstance(new_value,int):
      13              self.__price = new_value
      14 15      @price.deleter
      16      def price(self):
      17          del self.__price
      18  apple = Goods('apple',5)
      19  print(apple.price)
      20  apple.price = 'ashkaksk'
      21  del apple.price   # 并不能真的删除什么,只是调用对应的被@price.deleter装饰的方法而已
      22  print(apple.price)

       

反射

  1. 反射对象的实例变量/绑定方法

     1  class A:
     2      Role = '治疗'
     3      def __init__(self):
     4          self.name = 'alex'
     5          self.age = 84
     6      def func(self):
     7          print('wahaha')
     8          return 666
     9 10  a = A()
    11  print(getattr(a,'name')) # 反射对象的实例变量
    12  print(getattr(a,'func')()) # 反射对象的绑定方法

     

  2. 反射类的静态变量/(其他方法)

     1  class A:
     2      Role = '治疗'
     3      def __init__(self):
     4          self.name = 'alex'
     5          self.age = 84
     6      def func(self):
     7          print('wahaha')
     8          return 666
     9 10  a = A()
    11  print(getattr(A,'Role'))

     

  3. 反射模块中的所有变量

    1. 被导入的模块

      1  import a   # 引用模块中的任意的变量
      2  print(getattr(a,'sww'),a.sww)
      3  getattr(a,'sww')()
      4  print(getattr(a,'lst'),a.lst)
      5  print(getattr(a,'dic'),a.dic)
      6  print(getattr(a,'we'),a.we)

       

    2. 当前执行的模块—脚本

      1  import sys # 反射本模块中的名字
      2  cat = '小a'
      3  dog = '小b'
      4  def pig():
      5      print('小p')
      6  print(getattr(sys.modules['__main__'],'cat'))
      7  print(getattr(sys.modules['__main__'],'dog'))
      8  getattr(sys.modules['__main__'],'pig')()

       

  4. 判断这个被反射的内容是否存在或者是否可被调用

     1  class A:
     2      Role = '治疗'
     3      def __init__(self):
     4          self.name = 'alex'
     5          self.age = 84
     6      def func(self):
     7          print('wahaha')
     8          return 666
     9 10  a = A()
    11  # print(hasattr(a,'sex'))
    12  # print(hasattr(a,'age'))
    13  # print(hasattr(a,'func'))
    14  # if hasattr(a,'func'):
    15  #     if callable(getattr(a,'func')):
    16  #         getattr(a,'func')()

     

例子:

 1  class Payment:pass
 2  class Alipay(Payment):
 3      def __init__(self,name):
 4          self.name = name
 5      def pay(self,money):
 6          dic = {'uname':self.name,'price':money}
 7          print('%s通过支付宝支付%s钱成功'%(self.name,money))
 8  9  class WeChat(Payment):
10      def __init__(self,name):
11          self.name = name
12      def pay(self,money):
13          dic = {'username':self.name,'money':money}
14          print('%s通过微信支付%s钱成功'%(self.name,money))
15 16  class Apple(Payment):
17      def __init__(self,name):
18          self.name = name
19      def pay(self,money):
20          dic = {'name': self.name, 'number': money}
21          print('%s通过苹果支付%s钱成功' % (self.name, money))
22 23  class QQpay:
24      def __init__(self,name):
25          self.name = name
26      def pay(self,money):
27          print('%s通过qq支付%s钱成功' % (self.name, money))
28  import sys
29  def pay(name,price,kind):
30      class_name = getattr(sys.modules['__main__'],kind)  #  反射的方法
31      obj = class_name(name)
32      obj.pay(price)
33      # if kind == 'Wechat':                              #  旧方法,冗余
34      #     obj = WeChat(name)
35      # elif kind == 'Alipay':
36      #     obj = Alipay(name)
37      # elif kind == 'Apple':
38      #     obj = Apple(name)
39      # obj.pay(price)
40 41  pay('alex',400,'WeChat')
42  pay('alex',400,'Alipay')
43  pay('alex',400,'Apple')
44  pay('alex',400,'QQpay')

 

 

posted @ 2019-01-24 18:36  .如影随行  阅读(202)  评论(0编辑  收藏  举报