python面向对象进阶

  property 内置装饰器函数 只在面向对象中使用

from math import pi

class Circle:
    def __init__(self, r):
        self.r = r

    @property    # 将类似属性却需要操作得到的一些方法伪装成对象属性
    def perimeter(self):
        return 2 * pi * self.r

    @property
    def area(self):
        return pi * self.r ** 2


circle = Circle(5)
print(circle.perimeter)  # 调用方法和操作属性相同   本质上还是方法
print(circle.area)

   property 提供私有属性的查看,修改和删除

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

    @property
    def name(self):
        return self.__name

    @name.setter   # 修改 通过赋值来修改
    def name(self, new_name):
        self.__name = new_name

    @name.deleter
    def name(self):
        del self.__name


p = Person('zxc')
print(p.name)  # zxc
p.name = 'zxf'
print(p.name)  # zxf
del p.name  # 这里的del只是对应@name.deleter,主要看@name.deleter下面的方法执行了什么
# print(p.name)  # 报错 显示没有name属性

  classmethod和staticmethod

class Person:
    __key = '人类'

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

    @property
    def name(self):
        return self.__name

    @classmethod   # 将一个方法变成类中的方法,使这个方法可以直接被类调用而不用依托对象
    def change_key(cls, new_key):
        cls.__key = new_key


print(Person._Person__key)  # 人类
Person.change_key('human')
print(Person._Person__key)  # human
# 当这个方法的操作只涉及静态属性的时候 就应该使用classmethod来装饰这个方法
classmethod
class Login:
    def __init__(self,name,password):
        self.name = name
        self.pwd = password

    def login(self):
        pass

    @staticmethod  # 装饰一个完全跟类和对象没有关系的静态方法,通过类调用
    def get_usr_pwd():   # 静态方法
        usr = input('用户名 :')
        pwd = input('密码 :')
        Login(usr, pwd)
# 一般用在完全面向对象编程的时候
staticmethod

   isinstance和issubclass

class Person:
    pass


class Student(Person):
    pass


p = Person()
print(isinstance(p, Person))  # True  判断p是不是Person的实例化对象
print(issubclass(Student, Person))  # True  判断Student是不是Person的子类
print(issubclass(Person, Student))  # False

  __str__和__repr__

print('zxc')  # 打印对象时,就是调用对象的__str__方法
print(str('zxc'))  # str(obj) 本质就是 obj.__str__
print('zxc'.__repr__())  # 'zxc'   将对象原封不动的打印出来
print(repr('zxc'))   # repr(obj) 本质就是 obj.__repr__
# 格式化输出中的%s和%r就是使用的__str__和__repr__

  自己来个类测试一下

class Person:
    def __str__(self):
        return 'str zxc'
    pass


zxc = Person()
# print(zxc)  # not zxc  执行了Person类里面的__str__的方法
# 如果注释掉Person类里面的__str__的方法,找不到就到父类里面找,而在新式类中默认继承object,而object中带有__str__方法
print(zxc)  # 打印了对象的内存地址

  测试中发现个有趣的事情,__repr__是__str__备胎。

class Person:
    def __str__(self):
        return 'str zxc'

    def __repr__(self):
        return 'repr zxc'


zxc = Person()
print(zxc)  # str zxc

# 注释掉__str__方法
print(zxc)  # repr zxc  说明__repr__方法是__str__的备用方法,当类中找不到__str__就找__repr__,都没有 再去找父类

# 重新放开__str__方法,注释掉__repr__方法
print(repr(zxc))  # 打印了对象的内存地址  说明当类里找不到__repr__方法,就直接去父类里找,不能备用__str__

  __del__  构造析构函数

class File:
    def __del__(self):
        print('执行了!')


file = File()
del file   # 执行了!   再执行__del__函数后,进而删除了对象
print(f)  # 报错 显示找不到对象f

  可能用到的环境:

class File:
    def __del__(self):
        self.f.close()
        print('执行了关闭文件工作!')


file = File()
file.f = open('file', 'w')
del file  # 执行了关闭文件工作!
# 可以在删除一个对象之前进行一些收尾的工作

  __call__ 将一个类变为可调用的,当调用时执行__call__函数

class Person:
    def __init__(self, name):
        self.name = name

    def __call__(self, *args, **kwargs):
        print('对象的名字是%s' %self.name)


person = Person('zxc')
person()  # 对象的名字是zxc

# 也可以直接调用类
Person('zzy')()  # 对象的名字是zzy
原文地址:https://www.cnblogs.com/zxc-Weblog/p/8326146.html