专栏首页武军超python专栏2018年7月26日python中面向对象中的封装

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 条评论
登录 后参与评论

相关文章

  • 2018年7月25日python中面向对象编程的练习

    今天遇到的新单词: parameter  n参数 IndentationError  n缩进错误 formatting n格式化

    武军超
  • 2018-7-18pythoh中函数的参数,返回值,变量,和递归

    ********************************************************************************...

    武军超
  • 2018年7月22日用python写个人博客时遇到的问题

    今天遇到的新单词: subscript  n下标,脚注 integer    n整数,整型 function   n函数 variable   n变量 ...

    武军超
  • 100 Days of SwiftUI —— Day 10:类

    最初,类看起来与结构体非常相似,因为我们使用它们来创建具有属性和方法的新数据类型。但是,它们引入了一个新的,重要的且复杂的功能,即继承——使一个类在另一个类的基...

    韦弦zhy
  • ES6特性之:箭头函数

    在ES6的所有新特性中,箭头函数(Arrow Fucntion)算是我用的最频繁的特性之一了。

    一斤代码
  • Python学习记录day2

    Python是一门基于虚拟机的语言,pyc 是由py文件经过编译后二进制文件,py文件变成pyc文件后,加载的速度有所提高,而且pyc是一种跨平台的字节码,是由...

    py3study
  • Python 抓取数据存储到Redis中的操作

    redis是一个key-value存储结构。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(...

    砸漏
  • Python 魔法方法之__getattr__(self,name)

    当实例对象调用一个不存在的属性时,系统通常会报错,那有啥办法避免这种现象么,或者说自定义报错信息,答案是肯定的,我们可以通过定义__getattr__(self...

    cctester
  • 为什么要关注索引统计误差

    事情的起因是,我的朋友小明同学有一天突然发现有个SQL的执行计划出问题了。经过一番排查,居然发现是该表的辅助索引统计信息存在严重偏差。

    [3306 Pai ] 社区
  • 私有云中Kubernetes Clu

    Kubernetes Master HA架构图 ? 配置与说明 所有组件可以通过kubelet static pod的方式启动和管理,由kubelet st...

    Walton

扫码关注云+社区

领取腾讯云代金券