day 23 封装之如何隐藏、封装之隐藏属性的底层原理、封装的真正意义、property特性、绑定方法与非绑定方法

1、什么是封装

封:属性对外是隐藏的,但对内是开放的

装:申请一个名称空间,往里面装入一系列名字/属性

class People:
    __country='China' #_People__country='China'
    __n=100 #_People__n=100
    def __init__(self,name,age,sex):
        self.__name=name #self._People__name=name
        self.age=age
        self.sex=sex

    def eat(self):
        print('eat.....')
        print(People.__country) #People._People__country
        # print(self.__name) #self._People__name

# People.eat(123) #内部访问(访问的到)
print(People.__country)#外部访问,访问不到

property特性

property装饰器用于将被装饰的方法伪装成一个数据属性,在使用时可以不用加括号直接引用

class People:
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height
    @property #把bim技能伪装成特征
    def bmi(self):
        return self.weight / (self.height**2)

p1=People('egon',75,1.85)
print(p1.bmi)
property装饰器用于将被装饰的方法伪装成一个数据属性,在使用时可以不用加括号而直接引用
class People:
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height

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

peo1=People('egon',75,1.8)

peo1.height=1.85
print(peo1.bmi)


'''
class People:
    def __init__(self,name):
        self.__name=name

    @property # 查看obj.name
    def name(self):
        return '<名字是:%s>' %self.__name

    @name.setter #修改obj.name=值
    def name(self,name):
        if type(name) is not str:
            raise TypeError('名字必须是str类型傻叉')
        self.__name=name

    @name.deleter #删除del obj.name
    def name(self):
        # raise PermissionError('不让删')
        print('不让删除傻叉')
        # del self.__name

peo1=People('egon')
# print(peo1.name)

# print(peo1.name)

# peo1.name='EGON'
# print(peo1.name)

del peo1.name

'''


class People:
    def __init__(self,name):
        self.__name=name


    def tell_name(self):
        return '<名字是:%s>' %self.__name

    def set_name(self,name):
        if type(name) is not str:
            raise TypeError('名字必须是str类型傻叉')
        self.__name=name

    def del_name(self):
        print('不让删除傻叉')

    name=property(tell_name,set_name,del_name)


peo1=People('egon')

print(peo1.name)
peo1.name='EGON'
print(peo1.name)
del peo1.name

定位到属性操作三个点,查看 修改 删除
'''
1、绑定方法
    特性:绑定给谁就应该由谁来调用,谁来调用就会将谁当作第一个参数自动传入
         《《《精髓在于自动传值》》》

    绑定方法分为两类:
        1.1 绑定给对象方法
            在类内部定义的函数(没有被任何装饰器修饰的),默认就是绑定给对象用的
        1.2 绑定给类的方法:
            在类内部定义的函数如果被装饰器@classmethod装饰,
            那么则是绑定给类的,应该由类来调用,类来调用就自动将类当作第一个参数自动传入



2、非绑定方法
    类中定义的函数如果被装饰器@staticmethod装饰,那么该函数就变成非绑定方法
    既不与类绑定,又不与对象绑定,意味着类与对象都可以来调用
    但是无论谁来调用,都没有任何自动传值的效果,就是一个普通函数

非绑定方法其实就是一个函数


 
3 应用
    如果函数体代码需要用外部传入的类,则应该将该函数定义成绑定给类的方法
    如果函数体代码需要用外部传入的对象,则应该将该函数定义成绑定给对象的方法
    如果函数体代码既不需要外部传入的类也不需要外部传入的对象,则应该将该函数定义成非绑定方法/普通函数


'''

class Foo:
    @classmethod
    def f1(cls):  #绑定给类的
        print(cls)

    def f2(self):#b绑定给对象的
        print(self)


obj=Foo()
# print(obj.f2)#绑定给对象
# print(Foo.f1)#绑定给类的   不加@classmethod就是访问一个普通的函数

#绑定一共分为两类,一类是绑定给类的,一类是绑定给对象的

# Foo.f1()
# print(Foo)


# 1、f1绑定给类的
# 了解:绑定给类的应该由类来调用,但对象其实也可以使用,只不过自动传入的仍然是类
# print(Foo.f1)
# print(obj.f1)
# Foo.f1()
# obj.f1()
#
# 2、f2是绑定给对象的
# obj.f2()
# Foo.f2(obj)
#
import setting
# import uuid
#
class Mysql:
    def __init__(self,ip,port):
        self.uid=self.create_uid()#不需要装饰的任意定义的函数都是绑定给对象的
        self.ip=ip
        self.port=port

    def tell_info(self):
        print('%s:%s' %(self.ip,self.port))

#     @classmethod
#     def from_conf(cls):
#         return cls(settings.IP, settings.PORT)
#
#     @staticmethod
#     def func(x,y):
#         print('不与任何人绑定')
#
#     @staticmethod
#     def create_uid():
#         return uuid.uuid1()
#
# # 默认的实例化方式:类名(..)
# obj=Mysql('10.10.0.9',3307)

# 一种新的实例化方式:从配置文件中读取配置完成实例化
# obj1=Mysql.from_conf()
# obj1.tell_info()

# obj.func(1,2)
# Mysql.func(3,4)
# print(obj.func)
# print(Mysql.func)

print(obj.uid)

视频最后有老师总结

  

猜你喜欢

转载自www.cnblogs.com/wangmiaolu/p/9240407.html
今日推荐