python_fullstack基础(十六)-面向对象进阶

面向对象进阶

一、isinstance和issubclass内置方法

1、isinstance(obj,cls)

作用:检查是否obj是否是类cls的对象

2、issubclass(sub, super)

作用:检查sub类是否是super类的派生类

二、★反射(自省)

1、定义:

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

2、python中的反射:

通过字符串的形式操作对象相关的属性,python中的一切事物都是对象(都可以使用反射)。

3、四个可以实现自省的函数

①hasattr(obj,name):返回obj对象是否具有name所描述的属性
②getattr(obj,name):从obj对象中获取到name所描述的属性
③setattr(obj,name,value):给obj对象设置一个名为name的属性,属性值为value
④delattr(obj,name):从obj对象中删除名为name的属性
⑤反射的应用举例:
# ·反射对象中的属性和方法
class Foo:
    static_var = '类的静态变量'

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

    def say_hi(self):
        print('hello,%s' % self.name)

foo_obj = Foo('Yang',66)

# 用hasattr函数检测是否含有某属性
print(hasattr(foo_obj,'name'))
print(hasattr(foo_obj,'say_hi'))


# 用getattr获取属性
print(getattr(foo_obj,'name'))
func=getattr(foo_obj,'say_hi')
func()
print(getattr(foo_obj,'x','不存在啊')) #报错


#用setattr设置属性
setattr(foo_obj,'yo',True)
setattr(foo_obj,'show_name',lambda self:self.name+'yoyoyo')
print(foo_obj.__dict__)
print(foo_obj.show_name(foo_obj))

#用delattr删除属性
delattr(foo_obj,'age')
delattr(foo_obj,'show_name')
delattr(foo_obj,'not_exist_func') #不存在,则报错

print(foo_obj.__dict__)

# ·反射类的方法和属性
class Foo(object):
    static_var = "类的静态属性"

    def __init__(self):
        self.name = '人身苦短'

    def func(self):
        return '我用python'

    @staticmethod
    def bar():
        return 'bar func...'

print(getattr(Foo, 'static_var'))
print(getattr(Foo, 'func'))
print(getattr(Foo, 'bar'))

# ·反射模块的属性和方法(内置模块也是可以的)
'''
程序目录:
    module_test.py
    index.py

当前文件:
    index.py
'''
import module_test as obj

print(hasattr(obj, 'test'))

print(getattr(obj, 'test'))

# ·☆反射自己模块中的函数
import sys

def s1():
    print('s1')

def s2():
    print('s2')

this_module = sys.modules[__name__] # 返回自己的模块

print(hasattr(this_module, 's1'))
print(getattr(this_module, 's2'))

三、类的内置方法

1、__str__、__repr__

①注意:内置的类方法与内置函数之前的关系
②__str__方法
  • object类中实现了__str__,object中的__str__方法返回调用这个方法对象的内存地址
  • %s、str()、print()实际上都是执行内置方法__str__
  • 如果自定义类重写了__str__方法,则必须返回字符串
  • 如果类中没有__str__方法,会先找本类中的__repr__方法,若再没有则再找默认object类中的__str__
  • 如果类继承了自定义的父类,则如果没有__str__,则会继续找自定义父类中的__str__,若没有则找自己的__repr__,如果找不到则找自定义父类中的__repr__(repr是str的备胎,但str不是repr的备胎)
③__repr__方法
  • object类中实现了__repr__,object中的__repr__方法返回调用这个方法对象的内存地址
  • %r、repr() 实际上都是执行内置方法__repr__
  • 如果自定义类重写了__repr__方法,则必须返回字符串
  • 如果类中没有__repr__方法,则会找父类中的__repr__

2、__del__

①定义:析构方法,当对象在内存中被释放时,自动触发执行
②注意:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
③如果重写了__del__方法会先执行__del__中的代码,但最终仍会将对象在内存中释放
④应用举例:
class Foo:
def __del__(self):
        print('执行了__del__中的内容....')

f1 = Foo()
del f1
print(f1)

>>> 执行了__del__中的内容....
>>> Traceback (most recent call last):
      File "D:/practice.py", line 18, in <module>
        print(f1)
    NameError: name 'f1' is not defined

3、__call__

①定义:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
②应用举例:
class Foo:
    def __init__(self):
        pass

    def __call__(self, *args, **kwargs):
        print('调用__call__~~~')


obj = Foo()  # 执行 __init__
obj()  # 执行 __call__

4、__new__

①定义:python中对象的创建首先执行new内置方法,或者可以理解成python中类的构造函数
②应用实例:
  • 基本实例
            class Foo:
                def __init__(self):
                    print('in __init__')
                def __new__(cls, *args, **kwargs):
                    print('in __new__')
                    return object.__new__(Foo)

            f = Foo()

            >>> in __new__
            >>> in __init__
  • 单例模式举例:单例模式即所有创建的对象都是指向同一个对象,对任何对象的修改操作实际上都是对同一个对象的操作
            class Single:
                __instance = False
                def __init__(self):
                    pass
                def __new__(cls, *args, **kw):
                    if not hasattr(cls, '_instance'):
                        cls._instance = object.__new__(cls)
                    return cls._instance

            s1 = Single()
            s2 = Single()

            print(s1)
            print(s2)

            >>> <__main__.Single object at 0x00000000011B1B38>
            >>> <__main__.Single object at 0x00000000011B1B38>

2、__hash__

①应用实例:
            class A:
                def __init__(self):
                    self.a = 1
                    self.b = 2

                def __hash__(self):
                    return hash(str(self.a)+str(self.b))
            a = A()
            print(hash(a))

3、__eq__

①默认判断两个对象的内存地址是否相同
        class A:
            def __init__(self):
                self.a = 1
                self.b = 2

            def __eq__(self,obj):
                if  self.a == obj.a and self.b == obj.b:
                    return True
        a = A()
        b = A()
        print(a == b)

        >>> True

4、item系列—默认object类中没有包括item系列方法

①__getitem__
  • 定义:以[key]的方式取得类中的属性
  • 实例
                class Foo:
                    def __init__(self,attr1,attr2):
                        self.attr1 = attr1
                        self.attr2 = attr2
                    def __getitem__(self, item):
                        return self.attr1

                f = Foo('属性1','属性2')
                print(f['atr1'])
②__setitem__
  • 定义:以[key]的方式创建类的属性
  • 实例:
                class Foo:
                    def __init__(self,attr1,attr2):
                        self.attr1 = attr1
                        self.attr2 = attr2
                    def __setitem__(self, key, value):
                        return self.__setattr__(key,value)

                f = Foo('属性1','属性2')
                f['atr3'] = '属性3'
                print(f.__dict__)
                >>> {'attr1': '属性1', 'atr3': '属性3', 'attr2': '属性2'}
③__del__
  • 定义:调用del 类.属性的时候会执行该方法
  • 实例:
                class Foo:
                    def __init__(self,attr1,attr2):
                        self.attr1 = attr1
                        self.attr2 = attr2
                    def __delitem__(self, key):
                        del key

                f = Foo('属性1','属性2')
                del f['attr1']
                print(f.__dict__)

                >>> {'attr2': '属性2', 'attr1': '属性1'}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值