类的封装、类的property特性、类与对象的绑定方法和非绑定方法

类的封装

隐藏属性或方法,外部无法使用,内部可以使用,在类定义阶段就执行了,真的想引用,就使用_类名__属性名

在python中用双下划线的方式实现隐藏属性(设置成私有的)

类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式:

class A:
    __N=0  # 类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N
    
    def __init__(self):
        self.__X=10  # 变形为self._A__X
        
    def __foo(self):  # 变形为_A__foo
        print('from A')
        
    def bar(self):
        self.__foo()  # 只有在类内部才可以通过__foo的形式访问到.

这种自动变形的特点:

1.类中定的__x只能在内部使用,如self.__x,引用的就是变形的结果

2.这种变形其实正是针对内部的变形,在外部是无法通过__x这个名字访问到的

3.在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下划线开头的属性在继承给子类时,子类是无法覆盖的

类的property特性

被 @property 装饰的函数会从函数变成属性,也就是说直接.函数名,不需要加括号使用

class Foo:
    def func(self):
        pass

    # 定义property属性
    @property
    def prop(self):
        pass


# ############### 调用 ###############
foo_obj = Foo()
foo_obj.func()  # 调用实例方法
foo_obj.prop  # 调用property属性
  • 经典类中的属性只有一种访问方式,其对应被@property修饰的方法
  • 新式类中的属性有三种访问方式,并且对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法

由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

class Goods(object):
    def __init__(self):
        # 原价
        self.original_price = 100
        # 折扣
        self.discount = 0.8

    @property
    def price(self):
        # 实际价格 = 原价 * 折扣
        new_price = self.original_price * self.discount
        return new_price

    @price.setter
    def price(self, value):
        self.original_price = value

    @price.deleter
    def price(self):
        del self.original_price


obj = Goods()
obj.price  # 获取商品价格
obj.price = 200  # 修改商品原价
del obj.price  # 删除商品原价

类与对象的绑定方法和非绑定方法

对象的绑定方法

在类中没有被任何装饰器修饰的方法就是绑定到对象的方法,这类方法专门为对象定制

class Person:
    country='China'
    
    def __init__(self,name,age):
        self.name=name
        self.age=age
        
    def speak(self):
        print(self.name+','+str(self.age))
        
p=Person('kitty',18)
print(p.__dict__)

{'name': 'Kitty', 'age': 18}

类的绑定方法

类中使用@classmethod修饰的方法就是绑定到类的方法,这类方法专门为类定制,通过类名调用绑定到类的方法时,会将类本身当作参数传给类方法的第一个参数

class Operate_database():
    host = '192.168.0.5'
    port = '3306'
    user = 'abc'
    password = '123456'

    @classmethod
    def connect(cls):  # 约定俗成第一个参数名为cls,也可以定义为其他参数名
        print(cls)
        print(cls.host + ':' + cls.port + ' ' + cls.user + '/' + cls.password)


Operate_database.connect()

<class '_main_.Operate_database'>
192.168.0.5:3306 abc/123456

非绑定方法

在内部使用@staticmethod修饰的方法即为非绑定方法,这类方法和普通定义的函数没有区别,不与类或对象绑定,谁都可以调用,并且没有自动传值的效果

import hashlib

class Operate_database():
    def __init__(self, host, port, user, password):
        self.host = host
        self.port = port
        self.user = user
        self.password = password

    @staticmethod
    def get_passwrod(salt, password):
        m = hashlib.md5(salt.encode('utf-8'))  # 加盐处理
        m.update(password.encode('utf-8'))
        return m.hexdigest()


hash_password = Operate_database.get_passwrod('lala', '123456')  # 通过类来调用
print(hash_password)

f7a1cc409ed6f51058c2b4a94a7e1956

p = Operate_database('192.168.0.5', '3306', 'abc', '123456')
hash_password = p.get_passwrod(p.user, p.password)  # 也可以通过对象调用
print(hash_password)

0659c7992e268962384eb17fafe88364

简而言之,非绑定方法就是将普通方法放到了类的内部

posted @ 2019-06-20 16:58  小小罗code  阅读(179)  评论(0编辑  收藏  举报