2018年7月26日python中面向对象中的封装

今天遇到的新单词:
attribute   n属性
   

************************

面向对象的核心:类和对象
类就是类型,也就是数据类型,就是从一些具有相同特征的东西中抽象出来一个模型,给这个模型定义一些属性
对象就是包含这个模型中所有特征的一个具体的值

对象的属性也叫做成员变量
类中的方法也叫做成员方法

案例:
主人给宠物喂食[两个不同的类型创建的不同的对象,对象之间可以相互调用]
英雄对战[一个相同的类型创建的两个不同对象,对象之间的交互]

面向对象的开发方式是[函数和方法混合开发]
如果处理某个独立功能-> 封装成一个独立的函数,如:获取系统当前时间--封装成一个具体的功能函数,也就是和程序
数据没有关系,和系统由关系的,创建一个独立的函数
如果处理和某个数据关联的功能-> 将函数定义在类型中变成方法,通过调用方法执行
            
*****************************
          对象中的封装

面向对象的封装共有三种封装:1.数据的封装,2.方法的封装, 3.属性的封装
数据的封装:
就是把需要的数据定义为类型的属性,然后创建对象,给对象附上相应的值,这样的话数据的格式和和表示就是
固定的。这样的数据规范在面向对象中,是强制规定的!

方法的封装:
就是将函数写在类型的里面

属性的封装,为了不让别人直接访问对象的数据,所有有了类型属性的封装:
三年之前的项目开发中,人们的共识就是以一个下划线开头的属性是对象的私有属性,不能在外部调用,如self._name=name
但是共识并不能真正让所有人遵守,所以python中就增加语法限制属性,让属性私有化,不让外界直接访问
python中规定了,双下划线开头的属性是私有的,语法上外界不能直接访问,如self._ _name =name,将属性定位私有属性,
并固定必须用get,set方法才能访问对象中的数据,在外部无法直接调用,错误形式 s1._ _name = "小六",
正确的额使用方法是:s.set_name("汤姆") print("名字:%s" % s.get_name())


属性的封装依然存在问题:但是已经不是问题!
作为一个有经验的开发人员,你要知道怎么操作私有属性
知道:知道规范怎么操作;知道破坏性的语法怎么操作!

总结封装:
在python中,封装按照如下步骤进行操作
(1) 定义类型,所有属性私有化[双下划线开头]
(2) 每个属性提供set/get方法[赋值/取值]
命名规范:赋值:set_属性名称(..) 
取值:get_属性名称(..)
(3) 在get/set方法中,提供限制条件,让用户输入的东西真实符合生活。


怎么解决创建对象的时候用户输入的非法数据?
初始化数据的时候直接调用set方法
self.set_name(name)
self.set_age(age)

类型中的属性封装之后变成私有属性,必须要用提供get,set方法才能访问对象的数据,但是有一种方法,不用get,set方法也
可以直接访问对象的数据,这种方法了解就行,项目中千万不要写,项目中的修改个人数据必须要用get,set方法
这种方法就是通过 对象._类型名称__属性 可以直接操作私有属性,但是这是破坏性的
这种方法打破了属性的封装:这样的代码,坚决不要写!

s1._Student__name = "小六"
s1._Student__age = 32          
print("%s, 年龄:%s" % (s1.get_name(), s1.get_age()))


封装使用中的几种技巧:

1-限制类型中可以拓展的属性,为的就是不浪费定义的属性值,需要哪个定义哪个,下面有详细的代码
_ _slots_ _ =["_ _name", "age"],下滑线表示类型中定义的属性,受类型属性封装保护的属性,没有下划线的不受
属性封装的保护

2-同时,类型的属性可以自由地拓展,下面有详细的代码展示


3-property功能就是让开发者在需要使用get,set方法的时候,转换成直接就可以使用对象名.属性名操作属性
一个属性创建一个property,使用方法 s.name = "小武"
name = property(get_name, set_name, del_name)

4-将封装后的属性的访问方法转换为简单的对象名.属性名,下面有详细的代码展示
@property    #写在get函数上边
@name.setter   #写在set函数上边

*******************************
    1-用_ _slots_ _可以拓展和限制类型需要的属性
#对类型的成员属性的高级拓展,用__slots__限制可以拓展的属性名

class Student:

    #限制当前类型只能包含的属性
    _ _slots_ _ = ["__name", "age", "sex", "height"]  #类型中封装的用双下划线,可以拓展的属性用双引号引住

    def _ _init_ _(self, name):                       #不带下划线的也就是拓展的属性不受属性封装的保护
        self._ _name = name

    def get_name(self):
        return self._ _name

    def set_name(self, name):
        self._ _name = name

    name = property(get_name, set_name)

s = Student("小武")

s.name = "小六"

s.age = 18
s.sex = "男"

print(s.name, s.age, s.sex)
************************
   2-类型中属性的自由拓展

# python中对象的属性,可以脱离类型,自己扩展
# 强大的功能,但是同时也是一种极度破坏代码完整性的功能
# 慎重使用

class Student:
    def _ _init_ _(self, name):
        self._ _name = name

    def get_name(self):
        return self._ _name

    def set_name(self, name):
        self._ _name = name

    name = property(get_name, set_name)

s = Student("汤姆")

#下面是自定义的给对象增加属性,这个增加的属性不受封装的安全性保护,并且这些属性只是属于这一个对象
#其他对象还是只有类型里面规定的属性
s.age = 15

s.sex = "男"

s.height = 1.75

print(s.name, s.sex, s.height)


**********************
     3-property函数的具体使用方法
功能就是让开发者在需要使用get,set方法的时候,转换成直接就使用对象名.属性名操作属性,不用再调用get,set方法
需要每一个属性创建一个property
class Student:
    def _ _init_ _(self, name):
        self._ _name = name

    def get_name(self):
        return self._ _name

    def set_name(self, name):
        self._ _name = name

    def del_name(self):
        del self._ _name

    name = property(get_name, set_name, del_name)     #加上property就可以直接按对象名+属性名的方式操作属性
                                                        #不用再写get_name, set_name,不需要加方法名
s = Student("小武")

s.name = "小六"                #直接用对象名.属性名直接操作属性

print(s.name)

del s.name                    #删除对象的name属性

print(s.name)                 #打印出来会报错

*****************************
    4-下面这个把get,set方法转换会对象名.属性名操作类型的属性的方法了解就行,主要还是用上面那种方法

#属性的注解封装操作
class Student:
    def _ _init_ _(self, name):
        self._ _name = name

    @property
    def name(self):
        return self._ _name

    @name.setter
    def name(self, name):
        self._ _name = name

s = Student("小武")
s.name ="小六"
print(s.name)

原始操作
# u.set_name("汤姆")
# print(u.get_name())

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏WindCoder

《简明 Python 教程》学习笔记-控制流

1.为内建的raw_input函数提供一个字符串,这个字符串被打印在屏幕上,然后等待用户的输入。一旦我们输入一些东西,然后按回车键之后,函数返回输入。对于raw...

7500
来自专栏企鹅号快讯

Python类与面向对象

面向对象程序 程序 = 指令 + 数据 代码可以选择以指令为核心或以数据为核心进行编程 两种范例 1.以指令为核心:围绕"正在发生什么"编写 面向过程编程:程序...

27780
来自专栏PhpZendo

震惊 php empty 函数判断结果为空,但实际值却为非空

最近我在一个项目中使用 empty 时获取到了一些意料之外的结果。下面是我处理后的调试记录,在这里与你分享了。

15810
来自专栏企鹅号快讯

轻松学习Python:基础知识汇总

Python基础01 Hello World! Python命令行 假设你已经安装好了Python, 那么在命令提示符输入: python 将直接进入pytho...

19080
来自专栏猿人谷

C语言内存地址基础

从计算机内存的角度思考C语言中的一切东东,是挺有帮助的。我们可以把计算机内存想象成一个字节数组,内存中每一个地址表示 1 字节。比方说我们的电脑有 4K 内存,...

45480
来自专栏前端那些事

强大的原型和原型链

前两次总结了JavaScript中的基本数据类型(值类型<引用类型>,引用类型<复杂值>)以及他们在内存中的存储,对内存空间有了一个简单的了解,以及第二次总结了...

219100
来自专栏蛋未明的专栏

javascript中sort的盲点

20070
来自专栏机器学习从入门到成神

《你不知道的JavaScript》读书笔记(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/articl...

8510
来自专栏HTML5学堂

JS实战开发经验!函数多参数传参技巧

HTML5学堂-码匠:掌握JavaScript代码的你,一定编写封装过函数,为了提升函数的控制性,必不可少的就是参数,必选可选的一大堆参数罗列出来,函数调用貌似...

40850
来自专栏GreenLeaves

JavaScript之引用类型介绍

       引用类型的值(对象)是应用类型的一个实例。在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起,用于将数据和功能组织在一起...

21590

扫码关注云+社区

领取腾讯云代金券