写点什么

Python OOP-4

用户头像
若尘
关注
发布于: 2021 年 05 月 10 日
Python  OOP-4

8. 类的成员描述符(属性)

  • 类的成员描述是为了在类中对类的成员属性进行相关操作而创建的一种方式

  • get:获取属性的操作

  • set:修改或添加属性操作

  • delete:删除属性的操作

  • 如果想使用类的额成员描述符,大概有三种方法

  • 使用类实现描述器

  • 使用属性修饰符

  • 使用 property 函数

  • property 函数很简单

  • property(fget, fset, fdel, doc)

  • 无论哪种修饰符都是为了对成员属性进行相应的控制

  • 类的方式:适用多个类中的多个属性共用同一个描述符

  • property:适用当前类中使用,可以控制一个类中多个属性

  • 属性修饰符:适用于当前类中使用,控制一个类中的一个属性

9. 类的内置属性

    __dict__: 以字典的方式显示类的成员组成    __doc__: 获取类的文档信息    __name__: 获取类的名称,如果在模块中使用,获取模块的名称    __bases__: 获取某个类的所有父类,以元组的方式显示
复制代码

10. 类的常用魔术方法

  • 魔术方法就是不需要人为调用的方法,基本是在特定的时间自动触发

  • 魔术方法的统一特征,方法名被前后各两个下划线包裹

  • 操作类

  • __init__:构造函数

  • __new__:对象实例化方法,此魔术方法较特殊,一般不需要使用

  • __call__:对象当函数使用的时候触发

  • __str__:当对象被当作字符串使用的时候

  • __repr__:返回字符串

  • 描述符相关

  • __set__

  • __get__

  • __delete__

  • 属性操作相关

  • __getattr__:访问一个不存在的属性时触发

  • __setattr__:对成员属性进行设置的时候触发

  • 参数:

  • self 用来获取当前对象

  • 被设置的属性名称,以字符串形式出现

  • 需要对属性名称设置的值

  • 作用:进行属性设置的时候进行验证或者修改

  • 注意:在该方法中不能对属性进行赋值操作,否则死循环

  • 运算类相关魔术方法

  • __gt__:进行大于判断的时候触发的函数

  • 参数

  • self

  • 第二个参数是第二个对象

  • 返回值可以是任意值,推荐返回布尔值

11. 类和对象的三种方法

  • 实例方法

  • 需要实例化对象才能使用的方法,使用过程中可能需要截至对象的其他对象的方法完成

  • 静态方法

  • 不需要实例化,通过类直接访问

  • 类方法

  • 不需要实例化


# 属性案例# 创建Student类,描述学生类# 学生具有Student.name属性# 但name格式并不统一# 可以用增加一个函数,然后自动调用的方式,但很蠢class Student():    def __init__(self, name, age):        self.name = name        self.age = age                # 如果不想修改代码        self.setName(name)            # 介绍下自己    def intro(self):        print("Hai, my name is {0}".format(self.name))            def setName(self, name):        self.name = name.upper()        s1 = Student("RUO Chen", 19.8)s2 = Student("michi stangle", 24.0)s1.intro()s2.intro()
复制代码


Hai, my name is RUO CHENHai, my name is MICHI STANGLE
复制代码


# propertya 案例# 定义一个Person类,具有name,age属性# 对于任意输入的姓名,我们希望用大写方式保存# 年龄,我们希望内部统一用整数保存# x = property(fget, fset, fdel, doc)class Person():    '''    这是一个人,一个高尚的人,一个脱离了低俗趣味的人    他还他妈的有属性    '''    # 函数名称可以任意    def fget(self):        return self._name * 2        def fset(self, name):        # 所有输入的姓名以大写方式 保存        self.name = name.upper()    def fdel(self):        self._name = "NoName"            name = property(fget, fset, fdel, "对name进行操作")
复制代码


# 类的内置属性举例print(Person.__dict__)print(Person.__doc__)print(Person.__name__)# 元组形式显示所有的父类print(Person.__bases__) 
复制代码


{'__module__': '__main__', '__doc__': '\n    这是一个人,一个高尚的人,一个脱离了低俗趣味的人\n    他还他妈的有属性\n    ', 'fget': <function Person.fget at 0x000001FBBD3AFBF8>, 'fset': <function Person.fset at 0x000001FBBD3AF9D8>, 'fdel': <function Person.fdel at 0x000001FBBD3AF8C8>, 'name': <property object at 0x000001FBBD3B7BD8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}
这是一个人,一个高尚的人,一个脱离了低俗趣味的人 他还他妈的有属性 Person(<class 'object'>,)
复制代码


# init 举例class A():    def __init__(self, name = 0):        print("哈哈,我被调用了")        a = A()
复制代码


哈哈,我被调用了
复制代码


# __call__ 举例class A():    def __init__(self, name = 0):        print("哈哈,我被调用了")            def __call__(self):        print("我被调用again")        a = A()a()
复制代码


哈哈,我被调用了我被调用again
复制代码


# __str__ 举例class A():    def __init__(self, name = 0):        print("哈哈,我被调用了")            def __call__(self):        print("我被调用again")            def __str__(self):        return '666'        a = A()print(a)
复制代码


哈哈,我被调用了666
复制代码


# __getattr__class A():    name = "NoName"    age = 18        def __getattr__(self, name):        print("没找到")        print(name)    
a = A()print(a.name)print(a.addr)
复制代码


NoName没找到addrNone
复制代码


# __setattr__ 案例class Person():    def __init__(self):        pass        def __setattr__(self, name, value):        print("设置属性:{0}".format(name))        # 下面语句会导致问题,死循环        # self.name = value        # 此种情况,为了避免死循环,规定统一调用父类魔法函数        super().__setattr__(name, value)p = Person()print(p.__dict__)p.age = 18
复制代码


{}设置属性:age
复制代码


# __gt__
class Student(): def __init__(self, name): self._name = name def __gt__(self, obj): print("哈哈,{0} 会比 {1} 大吗?".format(self, obj)) return self._name > obj._name stu1 = Student("one")stu2 = Student("two")print(stu1 > stu2)
复制代码


哈哈,<__main__.Student object at 0x000001C15772EB38> 会比 <__main__.Student object at 0x000001C15772E550> 大吗?False
复制代码


# 三种方法的案例class Person():    # 实例方法    def eat(self):        print(self)        print("Eating......")    # 类方法    # 类方法的第一个参数,一般命名为cls,区别于self    @classmethod    def play(cls):        print(cls)        print("Playing......")            # 静态方法    # 不需要用第一个参数表示自身或者类    @staticmethod    def say():        print("Saying......")        yueyue = Person()
# 实例方法yueyue.eat()# 类方法Person.play()yueyue.play()# 静态方法Person.say()yueyue.say()
复制代码


<__main__.Person object at 0x000001C157766710>Eating......<class '__main__.Person'>Playing......<class '__main__.Person'>Playing......Saying......Saying......
复制代码


发布于: 2021 年 05 月 10 日阅读数: 12
用户头像

若尘

关注

还未添加个人签名 2021.01.11 加入

还未添加个人简介

评论

发布
暂无评论
Python  OOP-4