第四十三篇 面向对象进阶2

第四十三篇 面向对象进阶2

一、类的封装

封装:打包,封起来,装起来

1.封装分为两个层面

1.第一个层面:对象能拿到类的东西,但是类能拿到对象的东西吗?这里就存在一层封装

class Foo():
    count = 0
    print(count)

f = Foo()
print(f.count)  # 0
f.name = 'nick'  # 对对象进行了封装
print(Foo.name)

**2.第二个层面的:内部可以使用,外部不可以使用,在你需要封装的属性前面加上__**

class People():
    __love_people = 'male'
    print('in',love_people)

    def __nawan(self):
        print('nawan')
    def __nakuaizi(self):
        print('nakuaizi')
    def __chifan(self):
        print('chifan')

    def chifan_all(self):
        self.__nawan()
        self.__nakuaizi()
        self.__chifan()

print('out',People.__f1)

p  = People()
print('out',p.nawan())
print('out',p.nakuaizi())
print('out',p.chifan())

print('out',p.chifan_all())

3.对属性这个封装有什么用:藏起来了,保护了你的隐私,类内部的属性不想让其他人访问
4.对方法封装有什么好处:精简了代码,你吃饭就使用chifan这个方法就行了,不需要去关心其他的操作,并且外部调用者也不知道你内部发生了什么

2.应用

print('*'*50)
class People:
    def __init__(self,pwd):
        self.__pwd = pwd
    @property  # 方法不用加括号使用
    def pwd(self):
        return f'无法获取你的密码'

p = People('123')
print(p.pwd)
print(p.pwd)
class F1:
    __count = 0

f = F1()
print(f._F1__count)  # 如果你真的要拿,_类名__属性去拿(不可能这样做)
class Foo:
    def f1(self):
        print('FOO.f1')
    def f2(self):  # foo
        print('Foo.f2')
        self.f1()

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

foo = Bar()
foo.f2() # Foo.f2  # Bar.f1
class Foo:
    def __f1(self):  # _Foo__f1
        print('FOO.f1')
    def f2(self):  # foo
        print('Foo.f2')
        self.__f1()  # _Foo__f1
print(Foo.__dict__)
class Bar(Foo):
    def __f1(self):  # _Bar__f1
        print('Bar.f1')

bar = Bar()
bar.f2() # Foo.f2
# 封装其实在定义阶段就以己经执行了,会把私有属性__f1变成_Foo__f1,之后都不会做这种处理
class Foo():
    __count = 0

foo = Foo()
print(foo)


foo.__y = 1
print(foo.__y)

二、类的property特性

1. BMI(Body Mass Index):身体体质指数

男性体脂>25%,女性>33%是诊断为肥胖的标准

class People():

    def __init__(self,height,weight):
        self.height = height
        self.weight = weight

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

peo = People(1.8,70)
print(peo.height)
print(peo.bmi())
print(peo.bmi)

2.装饰器用法(只在Python3中使用)

1.property一般用在:本来是方法,但是他应该是属性的时候,我们就应该property

2.setattr 和 delattr

3.setattr 和 delattr这两个方法只能对属性修改和删除,也就是在使用了property之后使用

class People():

    def __init__(self,height,weight):
        self.height = height
        self.weight = weight

    @property  # 获取值的时候触发,你不需要加括号使用,不能加参数
    def bmi(self):
        return self.weight/(self.height**2)

    @bmi.setter  # 在修改bmi的时候触发,必须得加参数
    def bmi(self, value):
        print(f'你已经成功修改为{value}')

    @bmi.deleter  # 在删除bmi的时候触发,不能加参数
    def bmi(self):
        print('delter')

peo = People(1.8,70)
print(peo.bmi)

print('*'*50)
peo.bmi = 50

print('*'*50)
del peo.bmi

类属性用法(Python2的)

三、类与对象的绑定方法及非绑定方法

1.绑定方法:绑定的方法

class Foo:
    # 绑定给对象,只有对象能用,但是类也能使用,使用的时候必须得传参
    def f1(self):
        print(self)

    @classmethod  # 让被装饰的函数给类使用,约定俗称参数为cls
    # 绑定给类的方法,类能使用,对象也可以使用,但是参数依然是类
    def f2(cls):
        print(cls)

    # 什么都不绑定的,非绑定方法,定义了普通的函数
    @staticmethod
    def f3(self):
        print(self)

f = Foo()
f.f1()
Foo.f1(1111)

print('*' * 50)
Foo.f2()
f.f2()

print('*'*50)
Foo.f3(2222)
f.f3(2222)

2.什么时候使用?

  • 这个方法需要使用类做为参数的时候就得使用类绑定方法,@classmethod
class A:
    def __init__(self,name):
        self.name = name

    @classmethod
    def cla_pri(cls):
        print(f'{cls.__name__},{cls}')

class B(A):
    pass

A.cla_pri()
B.cla_pri()
x = B('x')
x.cla_pri()
'''
A,<class '__main__.A'>
B,<class '__main__.B'>
B,<class '__main__.B'>

'''
  • 这个方法需要使用对象作为参数的时候就得使用对象绑定方法
  • 这方法即不需要类作为参数又不需要对象作为参数,使用非绑定方法,@staticmethod

四、总结

1.封装:隐藏属性或方法,外部无法使用,内部可以使用,在类定义阶段就执行了,真的想引用,就使用_类名__属性名

2.隐藏模块内的函数/变量_x:from module import *(无法导入), from module import _x(不合理)

3.@property:被 @property 装饰的函数会从函数变成属性,也就是说直接.函数名,不需要加括号使用

4.@方法名.setter:被 @方法名.setter 装饰的函数,方法名修改,会执行这个装饰的函数

@bmi.setter
def set_bmi():
    print('setter')
peo.bmi = 40

5.@方法名.deleter:被 @方法名.deleter 装饰的函数,方法名删除,会执行这个装饰的函数

@bmi.deleter
def del_bmi():
    print('deleter')
del peo.bmi

6.python2中类属性调用的方法

7.对象的绑定方法:没有加任何装饰的方法就是对象的绑定方法

8.类的绑定方法:加了@classmethod装饰器的方法就是类的绑定方法

9.非绑定方法:加了@staticmethod装饰器的方法就是非绑定方法,其实就是一个普通的函数

猜你喜欢

转载自www.cnblogs.com/itboy-newking/p/11072038.html