首页 > 技术文章 > day26.面向对象-反射封装内置方法

jiuyachun 2019-04-29 11:21 原文

封装                

隐藏对象的属性和实现细节,近对外提供公共访问方式

广义:代码保护,面向对象思想

狭义:将属性,方法隐藏起来

 

class Person:
    __key = 123456                  # 私有的静态属性
    def __init__(self,name,passwd):
        self.name = name
        self.__passwd = passwd      # 私有的属性

    def __test(self):                # 私有方法
        print(self.__dict__)
        print('私有方法内部调用')        ## 只要在类的内部使用私有属性,就会自动带上_类名

    def test2(self):
        return self.__test            # 私有方法只能在内部调用

    def get_pwd(self):
        # return self.get_pwd
        return self.__passwd

alex = Person('alex',123456)
alex.__high = 170
# print(alex.getwd())             # 程序定义__私有属性,保存为了(_类__属性)的形式
print(alex.__high)              ## 在类的外部定义的双下划线方法,可以被调用,格式也有变化。
print(alex.get_pwd())
ret = alex.test2()
print(ret)
ret()
###############
170 123456 <bound method Person.__test of <__main__.Person object at 0x00000200B052EC50>> {'name': 'alex', '_Person__passwd': 123456, '__high': 170} 私有方法内部调用

 

小结:

所有的私有,都是在变量左边加双下划线

所有的私有,在类内部随便调用,不能在类外部使用,__dict__是投机取巧的方法

私有包括:私有属性,私有方法,私有静态

 几个内置函数            

property

伪装代码,让代码看起来更加合理

 

from math import pi
class Circle:
    def __init__(self,r):
        self.r = r

    @property               
    def perimeter(self):
        return 2 * pi * self.r
    @property
    def area(self):
        return self.r ** 2 * pi

c1 = Circle(5)
print(c1.area)        # 代码经过伪装,名词'类方法'看起来更像是属性更加合理
print(c1.perimeter)
##################
78.53981633974483 31.41592653589793

一个静态属性property本质就是实现了get,set,delete三种方法

set可以理解为修改

delete可以理解为删除

class Foo:
    @property
    def AAA(self):
        print('get的时候运行我啊')

    @AAA.setter
    def AAA(self,value):
        print('set的时候运行我啊')

    @AAA.deleter
    def AAA(self):
        print('delete的时候运行我啊')

#只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
f1=Foo()
f1.AAA
f1.AAA='aaa'
del f1.AAA
#########
get的时候运行我啊
set的时候运行我啊
delete的时候运行我啊

 怎么用,比如说

class Goods:

    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):        # setter要在self,后面加入一个参数,设置得参数
        self.original_price = value

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


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

 classmethod 和 staticmethod 类方法,静态方法

classmethon 可以把一个方法变成类方法,进而直接调用。不需要依赖对象

class Goods:
    __discount = 0.8                # 这里是我们定义的打折
    def __init__(self,name,price):
        self.name = name
        self.__price = price
    @property
    def price(self):
        return  self.__price * Goods.__discount  # 返回折扣价格

    # def change_discount(self,new_discount):     # 修改一个新的折扣
    #     Goods.__discount = new_discount
    @classmethod                        # 把一个方法变成类的方法,这个方法可以被类直接调用。不需要依赖任何对象
    def change_discount(cls,new_discount):      # 这里在定义类方法得时候,还需要再传入一个参数
        cls.__discount = new_discount

apple = Goods('apple',5)
# apple.change_discount(0.5)      # 这里我们使用苹果去定义整个商品的折扣是不合理的
# print(apple.price)
Goods.change_discount(0.5)
print(apple.price)

staticmethod 可以将一个与类无相关的伪装成类的属性

class Login:
    def __init__(self,name,password):
        self.name = name
        self.pwd = password
    def login(self):pass

    @staticmethod
    def get_usr_pwd():
        usr = input('用户名:')
        pwd = input('密码:')
        Login(usr,pwd)

Login.get_usr_pwd()

反射

大概是将字符串变成参数传递

class Teacher:
    dic = {'显示课程':'数学','显示班级':'2014届'}

    def show_price(self):
        print('工资5000快')

    @classmethod
    def func(cls):
        print('体育老师')

ret = getattr(Teacher,'dic')         # 1.调用静态属性:类的静态属性可以直接获取
print(ret)
tom
= Teacher() ret2 = getattr(tom,'show_price') # 2.调用对象属性:实例化一个类对象然后再获取其对象属性 # print(ret2) ret2() if hasattr(Teacher,'func'): # 一般 hasattr 和 getattr 一起使用,不存在则不报错 ret3 = getattr(Teacher,'func') # 3.调用类方法:类方法的调用,直接调用需要实例化 ret3() {'显示课程': '数学', '显示班级': '2014届'} 工资5000快 体育老师

 

 

 

 

 

 

 

 

 

 

 

 

 

            

推荐阅读