类的进阶三

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

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取到 类,很关键。类加括号实例化对象。

原文地址:https://www.cnblogs.com/654321cc/p/7561126.html