python学习 day23面向对象之封装应用与装饰器

封装之隐藏属性之理论知识

1、封装:把数据与功能整合到一起
2、在封装的基础上,我可以将装到对象或者类中的属性给隐藏起来

注意:

  • (1)在定义类或者初始化对象时,在属性前加__,就会将该属性隐藏起来
    但该隐藏起始只是一种变形_类名__属性名,并没有真的隐藏起来

  • (2)该变形操作是在类定义阶段扫描语法时发生的变形,类定义之后添加的__开头的属性不会发生变形

  • (3)该隐藏是对外不对内,类中可以直接调用’__名称’,类外则得用变形后名称调用

  • (4) 在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的

隐藏属性应用详解

1、把数据属性隐藏起来的意义是:在类内开放接口,让外界使用者通过接口来操作属性值,我们可以在接口之上附加任意的逻辑

白痴写法,用于理顺逻辑,瞟一眼即可,待会儿会讲到的装饰器会有更好的写法:

                             # 来严格控制外界使用者对属性的操作

class Student:
    __school = "oldboy"  # _Student__school = "oldboy"

    def __init__(obj, x, y, z):
        obj.__name = x  # obj._Student__name = x
        obj.__age = y
        obj.gender = z

    def __choose(self):  # obj._Student__choose
        print("%s 正在选课" % self.name)

    def get_name(self):
        print(self.__name)  # print(self._Student__name)

    def set_age(self,x):
        if type(x) is not int:
            print("年龄必须是整型,傻叉")
            return
        self.__age = x

    def get_age(self):
        print(self.__age)

    def del_age(self):
        del self.__age

stu_obj1 = Student("冯疯子", 18, "female")
# stu_obj1.get_name()


# stu_obj1.set_age("asfdasfdasfafd")
stu_obj1.set_age(19)
stu_obj1.get_age()
# print(stu_obj1.__dict__)

2、把功能属性隐藏起来:隔离复杂度

这个写法划重点,记笔记

class ATM:
    def __card(self):
        print('插卡')
    def __auth(self):
        print('用户认证')
    def __input(self):
        print('输入取款金额')
    def __print_bill(self):
        print('打印账单')
    def __take_money(self):
        print('取款')

    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()
        self.__print_bill()
        self.__take_money()

对类宝具之装饰器三天王

@property:提供属性数据的查改删接口

  • Python专门提供了一个装饰器property,可以将类中的函数“伪装成”对象的数据属性,对象在访问该特殊属性时会触发功能的执行,然后将返回值作为本次访问的结果
  • 不仅如此,它还能使函数名进化成装饰器,用于设置成修改、删除数据属性时触发

BMI公式案例:
BMI指数是用来衡量一个人的体重与身高对健康影响的一个指标,计算公式为

  • 体质指数(BMI)=体重(kg)÷身高^2(m)
class People:
    def __init__(self, name, weight, height):
        self.name = name
        self.__weight = weight
        self.height = height

	# bmi的计算与查看功能
    @property
    def bmi(self):
        return self.weight / (self.height ** 2)

	# __weight的查看功能
    @property
    def weight(self):
        if self.name == '跃上青空':
            return self.__weight - 20
        else:
            return self.__weight

	# __weight的设置功能
    @weight.setter
    def set_weight(self,x):
        if type(x) != int:
            print('修改的体重必须输入整数')
            return
        self.__weight = x

	# __weight的删除功能,这里禁止删除哦
    @weight.deleter
    def del_weight(self):
        print('休想销毁证据!')


obj = People('跃上青空', 56, 1.73)
obj.bmi  # 18 是正常体重哦

例二:直接调用property函数的写法(了解即可)

class Student:
    __school = "oldboy"  # _Student__school = "oldboy"

    def __init__(obj, x, y, z):
        obj.__name = x
        obj.__age = y
        obj.gender = z

    def get_name(self):
        print("访问控制")
        return self.__name

    def set_name(self,x):
        print("赋值控制")
        self.__name = x

    def del_name(self):
        print("删除控制")
        del self.__name

    def get_age(self):
        return self.__age

    def set_age(self, x):
        if type(x) is not int:
            print("年龄必须是整型,傻叉")
            return
        self.__age = x

    def del_age(self):
        print("不让删")


    age = property(get_age, set_age, del_age)  # 传入property函数的参数有先后顺序,功能顺序先后为:
    name = property(get_name, set_name, del_name)  #      查看--→修改--→删除

@classmethod:被装饰函数绑定给类,可以由类来调用,会把类当作第一个参数传入,其实对象也能正常调用

@staticmethod:被绑定函数既不与类绑定也不与对象绑定,就是一个普通的函数,谁都可以来调用,没有自动传参的效果

@classmethod与@staticmethod结合的案例:

  • 获取用户输入的IP与端口,或者从配置文件中传入
import uuid
import settings

class MySQL:
    def __init__(self,ip,port):
        self.mid = self.__create_id()
        self.ip = ip
        self.port = port

    def tell_info(self):
        print("%s:<%s:%s>" %(self.mid,self.ip,self.port))

    @staticmethod
    def __create_id():
        return uuid.uuid4()

    @classmethod
    def from_conf(cls):
        return cls(settings.IP, settings.PORT)

obj = MySQL("10.10.11.11",3306)
obj.tell_info()

obj1=MySQL.from_conf()
obj1.tell_info()

总结,类中的定义的函数

一 绑定方法:谁来调用就会将谁当作第一个参数传入

  • (1)绑定给对象的方法:类中定义的函数默认就是绑定给对象的方法,应该是由对象调用,会把对象当作第一个参数传入
  • (2)绑定给类的方法:在类中的函数上加一个装饰器@classmethod,该函数就绑定给类了,应该是由类来调用,会把类当作第一个参数传入

二 非绑定方法:既不与类绑定也不与对象绑定,就是一个普通的函数,谁都可以来调用,没有自动传参的效果,在函数上添加装饰器@staticmethod

猜你喜欢

转载自blog.csdn.net/wuzeipero/article/details/107819678
今日推荐