面向对象 --- 类的绑定方法,面向对象高阶

Posted whkzm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象 --- 类的绑定方法,面向对象高阶相关的知识,希望对你有一定的参考价值。

昨日回顾

类的绑定方法

classmethod(类的绑定方法)

翻译过来是一个类方法,是一个装饰器,可以装饰给类内部的方法,使该方法绑定给类来使用。

--- 对象的绑定方法的特殊之处:由对象来调用,会将对象当作第一个参数传给该方法

--- 类的绑定方法的特殊之处:由类来调用,会将类仿作第一个参数传给该方法

通过对象也可以调用,只是默认传递的第一个参数还是这个对象对应的类

staticmethod(非绑定方法)

是一个装饰器,可以装饰类内部的方法,使该方法即不绑定给对象,也不绑定给类。谁都可以调用,且没有自动传值的效果

简而言之,非绑定方法就是将普通方法放到类的内部

总结

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

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

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

面向对象高阶

isinstance

python内置的函数,用来传入两个参数,用于判断参数1是否是参数2的一个实例。

判断一个对象是否使一个类的实例,打印结果使True或者使False

print(isinstance(obj,class))

issubclass

python内置的函数,可以传入两个的参数,用于判断参数1是否使参数2 的子类。

判断一个类是否是另一个类的子类,打印结果使True或者使False

print(issubclass(子类,父类))

反射(*******************)

反射指的是通过 ’字符‘串’ 对 对象或者类的属性进行操作

-- hasattr:通过字符串,判断该字符串是否使对象或类的属性

print(hasattr(对象或者类,'属性'))

-- getattr:通过字符串,获取对象或类的属性

print(getattr(o,name,default))

-- setattr:通过字符串,设置对象或类的属性

setattr(p,'sal','3.0')
print(hasattr(p,'sal'))    # True

-- delattr:通过字符串,删除对象或类的属性。

delattr(p,'sal')
print(hasattr(p,'sal'))

魔法方法(类的内置方法)

凡是在类内部定义,以"__开头__结尾"的方法都称之为魔法方法,又称“类的内置方法”。

魔法方法会在某些条件成立时触发。

__str__:在打印对象时触发

__def__:对象被销毁前执行该方法,该方法会在最后执行

__getattr__:会在对象.属性时,“属性没有”的情况下才会触发

__setattr__:会咋“对象.属性 = 属性值”时触发

__call__:会砸对象你被调用时触发

__new__:会在__init__执行前触发

__init__:在调用类时触发

关于对__new__与__init__的理解在定义的类中,__new__是自动运行的,而且是隐藏起来的,当调用类进行实例化的时候,__new__与__init__一样是自动运行的,但是区别是__new__运行之后是产生一个空的对象的名称空间,然后__init__的作用是对这个产生的空的名称空间进行修饰。__new__后边跟的是(cls),指的是类,在执行的时候,传入的第一个对象是类,而__init__后边跟着的是(self),指的是对象,在执行的时候传入的第一个对象是对象本身。所以在运行 __init__的时候,其实是运行了__new___和__init__,一个负责搭建空的对象的名称空间,一个负责对这个空的名称空间进行装饰,也就是将__init__中的参数值添加到所产生的名称空间内。然而,当自己定义一个__new__的时候,会先执行自己定义的这个__new__,但是记住一定要记住最后一步一定要返回  object.__new__(cls),作用是来调用来调用object类中的__new__来产生一个空的名称空间,不然下边的__init__没有办法执行来对空的对象的名称空间进行修饰,因为就没有产生对象的名称空间.
class Foo(object):

    #
    def __new__(cls, *args, **kwargs):
        return object.__new__(cls)  # 真正产生一个空对象

    # 若当前类的__new__没有return一个空对象时,则不会触发。
    def __init__(self):
        print('在调用类时触发...')

    def __str__(self):
        print('会在打印对象时触发...')
        # 必须要有一个返回值, 该返回值必须时字符串类型
        return '[1, 2, 3]'

    def __del__(self):
        print('对象被销毁前执行该方法...')

    def __getattr__(self, item):
        print('会在对象.属性时,“属性没有”的情况下才会触发...')
        print(item)
        # 默认返回None, 若想打印属性的结果,必须return一个值
        return 111

    # 注意: 执行该方法时,外部“对象.属性=属性值”时无效。
    def __setattr__(self, key, value):
        print('会在 “对象.属性 = 属性值” 时触发...')
        print(key, value)
        print(type(self))
        print(self, 111)
        self.__dict__[key] = value

    def __call__(self, *args, **kwargs):
        print(self)
        print('调用对象时触发该方法...')
#
foo_obj = Foo()
print(foo_obj)
print(foo_obj.x)
print(foo_obj.x)
foo_obj.x = 123
print(foo_obj.x)
foo_obj()

单例模式

在类中,在调用一次类,就会进行一次类的实例化,就会产生一个对象的名称空间,再次调用的时候,会继续产生新的名称空间,在调用相同的文件的时候也是会产生不同的名称空间,这样的话比较浪费内存,所以就想对同一个文件打开的时候,对应的名称空间是同一个,方法如下:

class File:

    __instance = None

    # 单例方式1:
    # @classmethod
    # def singleton(cls, file_name):
    #     if not cls.__instance:
    #         obj = cls(file_name)
    #         cls.__instance = obj
    #     return cls.__instance

    # 单例方式2:
    def __new__(cls, *args, **kwargs):
        # cls.__new__(cls, *args, **kwargs)
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
            print(cls.__instance)
        return cls.__instance

    def __init__(self, file_name, mode='r', encoding='utf-8'):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def open(self):
        self.f = open(self.file_name, self.mode, encoding=self.encoding)

    def read(self):
        res = self.f.read()
        print(res)

    def close(self):
        self.f.close()


# 方式1:
# obj1 = File.singleton('jason雨后的小故事.txt')  # singleton(cls)
# obj2 = File.singleton('jason雨后的小故事.txt')  # singleton(cls)
# obj3 = File.singleton('jason雨后的小故事.txt')  # singleton(cls)
# obj1 = File('jason雨后的小故事.txt')
# obj2 = File('jason雨后的小故事.txt')
# obj3 = File('jason雨后的小故事.txt')
# print(obj1)
# print(obj2)
# print(obj3)

# 方式2:
obj1 = File('jason雨后的小故事.txt')  # singleton(cls)
obj2 = File('jason雨后的小故事.txt')  # singleton(cls)
obj3 = File('jason雨后的小故事.txt')  # singleton(cls)
print(obj1)
print(obj2)
print(obj3)

以上是关于面向对象 --- 类的绑定方法,面向对象高阶的主要内容,如果未能解决你的问题,请参考以下文章

Python 抽象篇:面向对象之高阶

python 课堂15 面向对象3 内部方法,类的定制

面向对象编程-总复习

面向对象

面向对象编程(类的绑定方法与非绑定方法)

scala面向对象.高阶函数,柯里化,Actor编程简介