Python 封装

Python 封装

一、封装

  • 面向对象的三大特性:

   封装、继承、多态

  • 概念

   将内容封装到"某"个地方,使用的时候直接去调用即可

  • 第一步:将内容封装到"某"处
#   创建类
class Foo(object):
  
    #   面向对象中.称为(构造函数  或  构造方法  或   初始化方法)根据类创建对象时自动执行
    def __init__(self,name,age):
        self.NAME = name
        self.AGE = age
  
#   根据类Foo创建对象. 自动执行Foo类的__init__方法
obj01 = Foo("Harry",27)         #   分别将Harry和27封装到【obj/self】的name and age属性中
obj02 = Foo("ZhanSan",26)       #   分别将ZhanSan和27封装到【obj/self】的name and age属性中  

  self 是一个形式参数. 当执行obj01 = Foo("Harry",27)时。   self 等于obj01

                obj02 = Foo("ZhanSan",26)时。 self 等于obj02

    所以. 内容其实被封装到了对象obj01 和obj02 中. 每个对象中都有name 和age属性.在内存中类似下图保存

 

  • 第二步:从"某"处调用被封装的内容

    被调用时封装的内容,有两种情况

    • 通过对象直接调用
    • 通过self简介调用

  1.通过对象直接调用封装的内容

    上图展示了对象obj01 和obj02在内存中保存的方式, 根据保存格式可以如此调用被封装的内容:对象.属性名 

#   创建类
class Foo(object):
  
  #   面向对象中.称为(构造函数  或  构造方法  或   初始化方法)根据类创建对象时自动执行
    def __init__(self,name,age):
        self.NAME = name
        self.AGE = age
  
#   根据类Foo创建对象. 自动执行Foo类的__init__方法
obj01 = Foo("Harry",27)
obj02 = Foo("ZhanSan",26)
  
print("My name is %s. %s years old this year"%(obj01.NAME,obj01.AGE))   # 直接调用obj01对象的name and age属性
print("My name is %s. %s years old this year"%(obj02.NAME,obj02.AGE))   # 直接调用obj02对象的name and age属性

  2.通过self间接调用封装的内容

    执行类中的方法时,需要通过self间接调用被封装的内容 

#   创建类
class Foo(object):
  
    #   面向对象中.称为(构造函数  或  构造方法  或   初始化方法)根据类创建对象时自动执行
    def __init__(self,name,age):
        self.NAME = name
        self.AGE = age
 
    def person(self):
        print("My name is %s. %s years old this year"%(self.NAME,self.AGE))
 
#   根据类Foo创建对象. 自动执行Foo类的__init__方法
obj01 = Foo("Harry",27)
obj02 = Foo("ZhanSan",26)
  
obj01.person() 
# Python默认会将obj01传给self参数.即:obj1.detail(obj1).所以.此时方法内部的 self = obj01,即:self.name 是 Harry;self.age 是 27
obj02.person() 
# Python默认会将obj02传给self参数.即:obj1.detail(obj2).所以.此时方法内部的 self = obj02,即:self.name 是 ZhanSan; self.age 是 26 

二、类中函数传参区分注意

  • 类中函数参数传参区分,重点 
#   创建类
class Foo(object):

    #   面向对象中.称为(构造函数  或  构造方法  或   初始化方法)根据类创建对象时自动执行
    def __init__(self,name,age):
        self.NAME = name    #   类的全局变量. 该类中方法都可以调用
        self.AGE = age

    def person_one(self):
        print("My name is %s. %s years old this year." % (self.NAME, self.AGE))

    def person(self,QQ):
        # print("%s %s My QQ number is %s"%(self.NAME,self.AGE,QQ))
        print("My QQ number is %s"%QQ)

obj01 = Foo("Harry",27)
obj02 = Foo("Gouer",26)

obj01.person_one()
obj02.person("287850394")

ps:函数person中跟的QQ为什么会被执行呢? 
     因为.我在调用它时可以指定传送的参数.不是必须封装的. 只要在调用时传送对应的参数即可.可以执行看效果
  • 类方法(函数)中修改封装值方法.当前类方法有效.其他类方法中无效 
#   创建类
class Foo(object):

    #   面向对象中.称为(构造函数  或  构造方法  或   初始化方法)根据类创建对象时自动执行
    def __init__(self,name,age, life_value=100, money=15000):
        self.NAME = name    #   类的全局变量. 该类中都可以调用
        self.AGE = age
        self.life_value = life_value
        self.money = money

    def person_one(self):    #    类方法.动态属性
        print("My name is %s. %s years old this year." % (self.NAME, self.AGE))

    def person(self,QQ):
        # print("%s %s My QQ number is %s"%(self.NAME,self.age,QQ))
        print("My QQ number is %s"%QQ)
        self.AGE = QQ   #   类方法(函数)中修改封装的值. 其他类方法(函数)中不受影响

obj01 = Foo("Harry",27)
obj02 = Foo("Gouer",26)

obj01.person_one()
obj02.person("287850394")
print(obj02.AGE)

 总结:综上所述. 对于面向对象中的封装来说. 其实就是使用构造方法将内容封装到对象中. 然后通过对象直接或者self简介获取b被封装的内容

   self.name = name and self.age = age 是类中的全局变量. 也可以说是将数据封装在这里面. 谁要谁直接使用self.XXXX调用即可.

  • 扩展:类方法中公有属性和私有属性:
    • 私有属性:仅类方法中自己可访问. 【self.__heart = "Normal"】外部不可访问. 内部可访问    
    elf.__heart = "Normal"    #   私有属性--仅类方法中自己可访问.【外部不可访问. 内部可访问】

    def get_heart(self): # 定义一个类方法.返回属性.让外部可调用. 但是不能修改.【对外部只提供只读接口】
    return self.__heart

    print(obj02._Foo__heart) # 强制访问私有属性
    • 公有属性:
    class Foo(object):
    nationality = "CN"  # 共有属性[在类里直接定义的属性即是共有属性]
    • 析构方法:    作用:程序收尾工作.实例被销毁的时候执行或程序结束时.变量删除时.    
    def __del__(self):        #  程序自己调用. 【实例销毁时自动调用】
    print("del....run....!..") 
  • 私有属性:【类中私有属性定义方法(类中可修改)】 and 【只允许外部访问私有属性但不能进行修改】 and 【强制访问】.写法!.
#   创建类
class Foo(object):

    #   面向对象中.称为(构造函数  或  构造方法  或   初始化方法)根据类创建对象时自动执行
    def __init__(self,name,age):
        self.NAME = name            #   类的全局变量. 该类中都可以调用 [称为:属性、成员变量]
        self.AGE = age
        self.__heart = "Normal"    #   私有属性--仅类方法中自己可访问.【外部不可访问. 内部可访问】

    def person_one(self):
        print("My name is %s. %s years old this year." % (self.NAME, self.AGE))
        self.__heart = "Die"
        print(self.__heart)

    def get_heart(self):        #   定义一个类方法.返回属性.让外部可调用. 但是不能修改.
        return self.__heart

    def person(self,QQ):
        # print("%s %s My QQ number is %s"%(self.NAME,self.age,QQ))
        print("My QQ number is %s"%QQ)
        self.AGE = QQ   #   类方法(函数)中修改封装的值. 其他类方法(函数)中不受影响

obj01 = Foo("Yuhonglin",27)
obj02 = Foo("ZhanSan",26)

obj01.person_one()
obj02.person("287850394")
print(obj02.get_heart())    #   查看私有属性
print(obj02.AGE)

print(obj02._Foo__heart)    #   强制访问私有属性

  • 公有属性:【类中公有属性定义方法(全局)所有成员都可调用】 and 【公有数据成员变量的修改和全局修改】.写法!.
#   创建类
class Foo(object):
    nationality = "CN"  #  公有属性. 公有属性无须实例化

    #   面向对象中.称为(构造函数  或  构造方法  或   初始化方法)根据类创建对象时自动执行
    def __init__(self,name,age):
        self.NAME = name            #   类的全局变量. 该类中都可以调用 [称为:属性、成员变量]
        self.AGE = age
        self.__heart = "Normal"    #   私有属性--仅类方法中自己可访问.【外部不可访问. 内部可访问】

    def person_one(self):
        print("My name is %s. %s years old this year." % (self.NAME, self.AGE))
        self.__heart = "Die"
        print(self.__heart)

    def get_heart(self):        #   定义一个类方法.返回属性.让外部可调用. 但是不能修改.
        return self.__heart

    def person(self,QQ):
        # print("%s %s My QQ number is %s"%(self.NAME,self.age,QQ))
        print("My QQ number is %s"%QQ)
        self.AGE = QQ   #   类方法(函数)中修改封装的值. 其他类方法(函数)中不受影响

Foo.nationality = "US"      #   修改所有的.通过全局修改那么就修改的是整个
obj01 = Foo("Yuhonglin",27)
obj01.nationality = "JP"    #   修改国籍. 只修改自己的.通过对象修改就只修改本身
obj02 = Foo("ZhanSan",26)   #    26 ZhanSan相当于是obj02的成员属性. 只属于obj02 . obj01一样

obj01.person_one()
obj02.person("287850394")
print(obj02.get_heart())    #   查看私有属性
print(obj02.AGE)

print(obj02._Foo__heart)    #   强制访问私有属性

print(obj01.nationality,obj02.nationality)
  • 析构方法
posted @ 2019-01-08 22:47  HonGIm  阅读(206)  评论(0)    收藏  举报