Python面向对象高阶

__slots__  限制 实例添加额外属性

了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:

class Student(object):
        __slots__ = ('name','age')   # 用tuple定义允许绑定的函数名字 

使用  __slots__ 要注意 __slots__  定义的属性 仅对 当前类实例起作用 对 继承的子类不起作用

class GraduateStudent(Student):
        pass


g = GraduateStudent()
g.score = 9999 # 继承的子类可以 实现修改
#除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。

@property

Python内置的@property装饰器就是负责把一个方法变成属性调用

class Room:
    def __init__(self,name,width,length):
        self.name=name
        self.width=width
        self.length=length

    @property
    def area(self):
        return self.width * self.length

r1=Room('alex',1,1)
print(r1.area)

 

定制类

Python 的 class有很多 特殊用的后汉书来帮我们定制类

__str__  __repr__

# 定义一个Student类 打印一个实例
class Student(object):
        def __init__(self, name):
                self.name = name

print(Student('Micheal'))
<__main__.Student object at 0x00000000028D1128> #__str__ 方法就是为了让这一行更加清晰

常用 __str__  __repr__用法是  组合起来用

class Student(object):
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return 'Student object (name=%s)' % self.name
    __repr__ = __str__
'''
str函数或者print函数--->obj.__str__()
repr或者交互式解释器--->obj.__repr__()
如果__str__没有被定义,那么就会使用__repr__来代替输出
注意:这俩方法的返回值必须是字符串,否则抛出异常
'''
 

Python式的  getter setter也是用 property实现的

class Foo:
        @property:
        def AAA(self):
                print('get用这个')
        @AAA.setter
        def AAA(self,value):
                print('set 用这个')
#只有在属性AAA定义property后才能定义AAA.setter
f1 = Foo()
f1.AAA  # 调用get
f1.AAA='AAAasd1'  #调用 set

另一种实现形式 是 __getattr__  __setattr__() 

class Foo:
    x=1
    def __init__(self,y):
        self.y=y

    def __getattr__(self, item):
        print('----> from getattr:你找的属性不存在')


    def __setattr__(self, key, value):
        print('----> from setattr')
        # self.key=value #这就无限递归了,你好好想想
        # self.__dict__[key]=value #应该使用它



#__setattr__添加/修改属性会触发它的执行
f1=Foo(10)
print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__)


#__getattr__只有在使用点调用属性且属性不存在的时候才会触发
f1.xxxxxx

__call__  当我们调用实例方法时  或许会 使用   isinstance(obj)调用  也可以 使用 __call__方式 使用

枚举类的用法

from enum import Enum
class Gender(Enum):
    Male = 0
    Female = 1

class Student(object):
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
bart = Student('Bart', Gender.Male)

元类 的 内容暂时理解很模糊 通读了一遍   廖雪峰老师的 元类介绍

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319106919344c4ef8b1e04c48778bb45796e0335839000

纵有疾风起,人生不言弃!
原文地址:https://www.cnblogs.com/poetl/p/8401238.html