zoukankan      html  css  js  c++  java
  • 类的进阶三

    一 私有静态属性,私有方法,私有属性

    class A:
        __role='英文单词'
        def __init__(self,name):
            self.__name=name
        def __a(self):
            pass
        def b(self):
            pass
    print(A.__dict__)
    A.__role='汉语拼音'
    print(A.__dict__)

      输出:

    {'__module__': '__main__', '_A__role': '英文单词', '__init__': <function A.__init__ at 0x0000020A01DB9BF8>, '_A__a': <function A.__a at 0x0000020A01DB9F28>, 'b': <function A.b at 0x0000020A01DD6048>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
    {'__module__': '__main__', '_A__role': '英文单词', '__init__': <function A.__init__ at 0x0000020A01DB9BF8>, '_A__a': <function A.__a at 0x0000020A01DB9F28>, 'b': <function A.b at 0x0000020A01DD6048>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None, '__role': '汉语拼音'}

      私有是在定义阶段变量名前加上__。查看__dict__,会发现实际存储的是  _类名__属性名。

      调用阶段__变量名,就没有你什么事了,该咋地咋地。

       PS 私有方法的用处:

        1 有一些方法的返回值只是用来作为中间结果

        2 父类的方法不希望子类继承,子类没法继承父类的__属性。

        实例:    

    class People:
        def __init__(self,name,pwd):
            self.name=name
            self.__pwd=pwd
        def __hashpwd(self):              #返回值作为中间结果
            return hash(self.__pwd)
        def login(self,pwd_info):
            return hash(pwd_info)==self.__hashpwd()
    egon=People('egon','123')
    print(egon.login('1234'))

      输出:

    False

    二  property属性。

      @property装饰器是负责把一个方法变为属性调用。

      在python中,property( )是一个内置函数,用来创建和返回一property对象 x 。

      property对象 x 有三种方法,x.getter(),x.setter(),x.deleter()。

      其中x.setter()本身也是装饰器,负责把一个setter方法变成属性赋值。

      property广泛应用在类的定义中,可以让定义者写出剪短的代码,同时保证了对参数进行必要的检查,这样程序运行时就减少了出错的可能性。

      输出:

    class Shop:
        discount=0.75
        def __init__(self,price):
            self.__price=price
    
        @property
        def price(self):                                        #@property 装饰器将price方法变成Shop对象的一个属性。price变成一个对象,进化了,拥有了setter,deleter方法
            return self.__price * Shop.discount
        @price.setter                                           #@price.setter装饰器, 被装饰的price执行=赋值操作时,执行相关的代码。                
        def price(self,new_price):
            self.__price=new_price
            print('执行setter语句')
            print('--------------')
        @price.deleter
        def bb(self):                                           #被装饰的bb,如果执行del语句,则执行动态属性内的代码
            print('执行deleter语句')
            print('---------------')
    apple=Shop(1000)
    print(apple.price)
    print(apple.__dict__)
    apple.price=10000
    print(apple.price)
    print(apple.__dict__)
    del apple.bb
    apple.p=100000
    print(apple.__dict__)

      输出:

    750.0
    {'_Shop__price': 1000}
    执行setter语句
    --------------
    7500.0
    {'_Shop__price': 10000}
    执行deleter语句
    ---------------
    {'_Shop__price': 10000, 'p': 100000}

      PS: 

        property函数实现了统一访问原则。统一访问原则就是代码不应由‘属性’ 是通过字段实现还是方法实现而受影响。如果没有property属性,有时候加()调用方法,有实际不加()调用属性。

        property实现了都不加( )调,这就叫统一访问原则。

    三 封装

      封装的原因:

        1 保护隐私

        2 隔离复杂度

      封装原则:

        1 把不需要对外显示的数据都隐藏起来

        2 把属性隐藏,对外提供公共接口

      封装的方法

        1 封装数据: 私有属性  __

        2  property属性

      封装的分类:很重要 !!!

        1 把同一类方法封装到类中

          class File:增删改查

          class DB:增删改查

        2 把数据封装到对象中

          class File:

            def __init__(self,name,age):

              self.name = name

              self.age = age

            ....

      示例:

    class People:
        def __init__(self,name,age,salary):
            self.__name=name                  #数据的封装
            self.__age=age
            self.__salary=salary
        @property                             #数据的封装,统一访问原则
        def name(self):                       #属性隐藏,对外部提供接口
            return self.__name
        @name.setter                          #装饰器 对外提供接口。接口内可以加入逻辑代码
        def name(self,x):                     #执行’改’时,执行下面代码
            if not type(x)==str:
                raise TypeError('请输入字符串!')
            self.__name = x
        @name.deleter
        def name(self):                       #对外提供接口的时候,可以加入逻辑代码
            raise PermissionError('不允许删!')
    egon=People('egon',35,2500)
    print(egon.name)
    egon.name=123
    print(egon.name)
    del egon.name                              #代码执行会报错,因为上面逻辑设定。

      输出:会报错,两个地方有错误。

    四 staticmethod 静态方法,classmethod 类方法

      staticmethod,不需要使用对象的属性和类的属性。

      classmethod,,传一个类的参数,不需要使用对量的属性,只需要使用类的属性。绑定给类。

      普通方法:传一个对象的参数,需要使用对象和类的属性,绑定给对象。

    class Foo:
        @classmethod
        def foo(cls):
            pass
        def bar(self):
            pass
    f=Foo()
    print(Foo.foo)
    print(f.bar)

      输出:

      都是绑定关系。

    <bound method Foo.foo of <class '__main__.Foo'>>
    <bound method Foo.bar of <__main__.Foo object at 0x0000018420DAEBE0>>

       classmethod的应用

    import settings
    class Foo:
        def __init__(self,ip,port):
            self.ip=ip
            self.port=port
        @classmethod
        def bar(cls):                              #绑定给类,把类传进来了。有了这个类,可以定制任意的逻辑,实现了自己想怎么执行就怎么执行
            obj=cls(settings.ip,settings.port)     #这一步是拿到了类,正常实例化的过程,obj就是Foo的一个对象。拿到了类,想咋地咋地
            obj.x=1111111111111111111111           #想咋地咋地
            return obj                             #最根本的是把类传进来,在foo函数内部拿到了这个类

      简单来说,可以借用classmethod取到 类,很关键。类加括号实例化对象。

  • 相关阅读:
    [原创]网页级在线性能测试网站介绍
    [原创]浅谈测试团队文化
    [原创]浅谈自动化测试中的金字塔模型理解
    [原创]如何在面试时选择合适的测试人员?
    [原创]浅谈怎么写周报
    [原创]Windows下调试工具介绍
    [原创]浅谈我对持续集成的理解
    [原创]IBM AppScan工具培训
    [原创]Jenkins持续集成工具介绍
    [原创]什么是信息安全资产管理?
  • 原文地址:https://www.cnblogs.com/654321cc/p/7561126.html
Copyright © 2011-2022 走看看