Python day25:封装

封装:在程序设计中,封装(Encapsulation)是对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,其含义是其他程序无法调用。要了解封装,离不开“私有化”,就是将类或者是函数中的某些属性限制在某个区域之内,外部无法调用。
1、在封装的基础上,我可以将装到对象或者类中的属性给隐藏起来
注意:
(1)在定义类或者初始化对象时,在属性前加__,就会将该属性隐藏起来
但该隐藏其实只是pycharm把这个变量名变为另一个命名方式,并没有真的隐藏起来,如

# 原本定义
self.name = name
# 隐藏起来
self.__name = name
'''
一种变形_类名__属性名,其实是把他变成_类名__属性名
'''

(2)该变形操作是在类定义阶段扫描语法时发生的变形,类定义之后添加的__开头的属性不会发生变形
(3)该隐藏是对外不对内
(4)在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的

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)

stu_obj1 = Student("冯疯子", 18, "female")
stu_obj1.__x=111
print(stu_obj1.__dict__)
print(stu_obj1.__x)

print(stu_obj1.__dict__)
print(stu_obj1._Student__name)

print(Student.__dict__)
print(Student._Student__school)
print(stu_obj1._Student__school)

隐藏属性的意义何在
1、把数据属性隐藏起来的意义是:我们可以使用接口(其实就是函数),把我们想让使用者使用的功能加以限制,比如我们可以先在函数里经过一系列的逻辑运算,来控制外界使用者对属性的操作。
以下例子,为实现对输入年龄的类型做控制,正在原来的方法中,age没办法控制输入的类型,可以是int,也可以是str,如age='haavavlvl'

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()

a=ATM()
a.withdraw()

至此,我们就通过封装的隐藏属性与提供接口实现了创建对象时属性的控制

2.property(特性)
property是一个特殊的属性,访问它时会执行一段功能(函数),他是一个装饰器

例1计算bmi指数
class People:
    def __init__(self, name, height, weight):
        self.name = name
        self.height = height
        self.weight = weight

    @property
    def bmi(self):
        return self.weight / (self.height ** 2)


p = People('egon', 1.81, 70)
p.height = 1.84
# 不加装饰器property时
print(p.bmi())
# 加装饰器时候
print(p.bmi)

例2: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)
    name = property(get_name, set_name, del_name)


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

# print(stu_obj1.age)
# stu_obj1.age = "19"
# del stu_obj1.age
# print(stu_obj1.age)


print(stu_obj1.name)
# stu_obj1.name="EGON"
# del stu_obj1.name

例3:property的新式用法
class Student:
    __school = "oldboy"  # _Student__school = "oldboy"

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

    @property
    def name(self):
        print("访问控制")
        return self.__name

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

    @name.deleter
    def name(self):
        print("删除控制")
        del self.__name

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

3.类方法(classmethod)与静态方法(staticmethod)
绑定方法:
1、类中定义的函数默认就是绑定给对象的方法,应该由对象调用,会把对象当做第一个参数
2、若使用classmethod装饰器,就会把函数绑定给类,pycharm会自动帮你传一个形参,cls,表示该函数绑定给类,应该由类来调用,会把类当做第一个参数

@classmethod
    def f1(cls):
        print(cls)

3、若使用静态方法static装饰器,表示不与类绑定也不与对象绑定,就是普通函数,需要什么参数就传什么参数

@staticmethod
    def f2(x,y,z):
        print(x,y,z)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342