第四天,还是不知道说些什么好,哎!封装、特性property、绑定方法与非绑定方法,第三十七天

从他的身上看到了自己从前的影子,原来这样的人是这么的令人生厌,幸好自己从那股烂泥潭中走了出来,万幸呀!以后做事不求能做到多好,只愿不做坏每一件事。也希望自己能早日摆脱从前的自己对自己造成的影响,尽量找到一群上进、有思想、谦逊的人。不多说了,这个问题都存在四天了,还没有思路怎么解决,真是无语,成长路上总有蠢人挡路。

1、封装

什么是封装

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

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

为什么要封装

    封装数据属性的目的

        首先定义属性的目的就是为了给类外部的使用对象使用的

        隐藏之后是为了不让外部使用直接使用,需要类内部开辟一个接口

        然后让类外部的使用通过接口来间接地操作隐藏的属性

        精髓在于:我们可以在接口之上附加任意逻辑,从而严格控制使用者对属性的操作

    封装函数属性

        首先定义属性的目的就是为了给类外部的使用使用的

        隐藏函数属性是为了不让外部使用直接使用,需要类内部开辟一个接口

        然后在接口内去调用隐藏的功能

        精髓在于:隔离了复杂度

如何封装

如何隐藏:在属性前加上__开头

1、这种隐藏仅仅只是一种语法上的变形操作

2、这种语法上的变形只在类定义阶段发生一次,因为类体代码金金只在类定义阶段检测一次

3、这种隐藏是对外不对内的,即在类的内部可以直接访问,而在类的外部无法直接访问,原因是在类定义

阶段,类体内代码统一发生了一次变形

4、如果不想让子类的方法覆盖父类的,可以将该方法名前加一个开头

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)

peo1=People('egon',18,'male')
peo1.eat()
print(peo1.__name)

print(People.__dict__)
print(People.__country)
print(People._People__country)

People.__x=11
print(People.__dict__)


peo1=People('egon',18,'male')
print(peo1.__dict__)
peo1.__x=111
print(peo1.__dict__)

class Foo:
    def __f1(self): #_Foo__f1
        print('Foo.f1')

    def f2(self):
        print('Foo.f2')
        self.__f1() #self._Foo__f1

class Bar(Foo):
    def __f1(self): #_Bar__f1
        print('Bar.f1')

obj=Bar()
obj.f2()




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

    def tell_info(self):
        print('%s:%s' %(self.__name,self.__age))

    def set_info(self,name,age):
        if type(name) is not str:
            # print('用户名必须为str类型')
            # return
            raise TypeError('用户名必须为str类型')

        if type(age) is not int:
            # print('年龄必须为int类型')
            # return
            raise TypeError('年龄必须为int类型')
        self.__name=name
        self.__age=age

peo1=People('egon',18)
peo1.name=123
peo1.age
peo1.tell_info()

peo1.set_info('egon',19)
peo1.tell_info()

2、特性property

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

3、绑定方法与非绑定方法

1、绑定方法

特性:绑定给谁就应该由谁来调用,谁来调用就会将谁当作第一个参数自动传入

精髓在于自动传值

绑定方法分为两类

    1、绑定给对象方法

    在类内部定义的函数(没有被任何装饰器修饰的),默认就是绑定给对象用的

    2、绑定给类的方法

    在类内部定义的函数如果被装饰器@classmethod装饰

    那么则是绑定给类的,应该由类来调用,类来调用就自动将类当作第一个参数自动传入

2、非绑定方法

类中定义的函数如果被装饰器@staticmethod装饰,那么该函数就变成非绑定方法

即不与类绑定,又不与对象绑定,意味着类与对象都可以来调用

但是无论谁来调用,都没有任何自动传值的效果,就是一个普通函数

3、应用

如果函数体代码需要用外部传入的类,则应该将该函数定义成绑定给类的方法

如果函数体代码需要用外部传入的类,则应该将该函数定义成绑定给对象的方法

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

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

    def f2(self):
        print(self)


obj=Foo()
print(obj.f2)
print(Foo.f1)

Foo.f1()
print(Foo)


1f1绑定给类的
了解:绑定给类的应该由类来调用,但对象其实也可以使用,只不过自动传入的仍然是类
print(Foo.f1)
print(obj.f1)
Foo.f1()
obj.f1()

2f2是绑定给对象的
obj.f2()
Foo.f2(obj)

import settings
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)

猜你喜欢

转载自blog.csdn.net/weixin_42157426/article/details/80844147