当前位置 : 主页 > 手机开发 > 其它 >

面向对象2

来源:互联网 收集:自由互联 发布时间:2021-06-19
目录 一.元类(type) 二.反射 三.函数和方法的区别 四.特殊的双下方法 五.单例模式 一.元类(type) type元类 又称 构建类 。 python中一切皆对象,类也是一个对象。python中大多数内置的类(包括

目录

  • 一.元类(type)
  • 二.反射
  • 三.函数和方法的区别
  • 四.特殊的双下方法
  • 五.单例模式

一.元类(type)

type元类又称构建类

python中一切皆对象,类也是一个对象。python中大多数内置的类(包括object)以及自己定义的类,都是由type元类创造的。

1.type获取对象从属的类

# 以下三种方法得到各自从属的类str、list、tuple
print(type('123'))    #<class 'str'>
print(type([1,2,3]))  #<class 'list'>
print(type((1,2,3)))  #<class 'tuple'>

#str、list、tuple都是源码中的类,同属于type元类
print(type(str))      #<class 'type'>
print(type(list))     #<class 'type'>
print(type(tuple))    #<class 'type'>

2.type和object的关系

type和object的关系比较特殊。了解即可。

# object类是type类的一个实例
print(type(object))   #<class 'type'>

# object类是type类的父类
print(issubclass(type,object))   # True

二.反射

反射是程序对自己内部代码的一种自省方式。

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

下面通过四种方式实现代码自省(反射)

1.对对象的反射

class A:
    country = "中国"
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def func(self):
        print("in A func")
        
obj = A("alex",11)
print(hasattr(obj,"name"))           # True 判断obj对象是否有name属性
print(getattr(obj,"age",None))       # 11   得到obj的age属性,默认得到None
getattr(obj,"func")()
setattr(obj,"name","wusir")
delattr(obj,"name")

2.对类的反射

class A:
    country = "中国"
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def func(self):
        print("in A func")

print(hasattr(A,'country'))          # True
getattr(A,"func")(1)

3.从其他模块

# module_test.py
def test():
    print("from the test")

    
# index.py
import module_test as obj

print(hasattr(obj,'test'))     # True
getattr(obj,"test")()          # 打印 from the test

4.从当前模块

import sys
def func():
    print("func")

current_modules = sys.modules[__name__]   # 得到当前文件这个模块
hasattr(current_modules,"func")           # True 
getattr(current_modules,"func")()         # 打印func

三.函数和方法的区别

函数都是显性传参,方法都是隐形传参(谨记)

以下有两种方法区分方法和函数:

1.打印函数名

通过类名调用类中的实例方法叫做函数

通过对象调用类中的实例方法叫方法

def func1():
    pass

class A:
    def func(self):
        pass

print(func1)        # <function func1 at 0x000001B5A5A0A8C8>
print(A.func)       # <function A.func at 0x000001B5A5A0A950>    
obj = A()
print(obj.func)     # <bound method A.func of <__main__.A object at 0x000001B5A5A084A8>>

类中的静态方法其本质就是函数,类中的类方法就是方法

class A:
    @staticmethod
    def func1():
        pass
    @classmethod
    def func2(cls):
        pass


print(A.func1)     # <function A.func1 at 0x000002D6FD10A9D8>
a = A()
print(a.func1)     # <function A.func1 at 0x000002D6FD10A9D8>
print(A.func2)     # <bound method A.func2 of <class '__main__.A'>>
print(a.func2)     # <bound method A.func2 of <class '__main__.A'>>

2.借助模块判断

FunctionType 判断是否是函数
MethodType 判断是否是方法

from types import FunctionType
from types import MethodType

def func():
    pass
class A:
    def func(self):
        pass
obj = A()

print(isinstance(func,FunctionType))
print(isinstance(A.func,FunctionType))
print(isinstance(obj.func,FunctionType))
print(isinstance(obj.func,MethodType))

四.特殊的双下方法

双下方法是特殊方法,是由python解释器提供的。

不同的双下方法有不同的触发方式。

1.__len__

len('alex')      # 自动执行'alex'所属类(str)的__len__方法
len([1,2,3])     # 自动执行[1,2,3]所属类(list)的__len__方法

class B:
    def __len__(self):
        return 666
b = B()
len(b)            # 自动执行对象b所属类B的__len__()方法

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()
hash(a)   # 自动执行a的所属类A的__hash__方法

3.__str__

在打印对象或者str()方法时,自动执行对象所属类的__str__方法

class A:
    def __init__(self):
        pass
    def __str__(self):
        return '太白'
a = A()
print(a)     # 自动执行a所属类A的__str__方法

4.__repr__

repr()执行对象所属类中的__repr__方法,返回对象的原有形态

class A:
    def __init__(self):
        pass
    def __repr__(self):
        return '太白'
a = A()
repr(a)      # 自动执行a所属类A的__repr__方法

5.__call__

对象(),自动触发执行对象从属类的__call__方法

class Foo:
    def __init__(self):
        pass
    
    def __call__(self, *args, **kwargs):
        print("__call__")

obj = Foo()
obj()     # 打印 __call__
# 如果类中没有__call__方法,报错:TypeError: 'Foo' object is not callable

6.__eq__

class A:
    def __init__(self):
        self.a = 1
    def __eq__(self, other):
        if self.a == other.a:
            return True
x = A()
y = A()
print(x == y)  # 自动执行x和y从属类A的__eq__方法,将x传给self,y传给other

7.__del__

析构方法。(python中的垃圾回收机制,程序执行完,自动回收)

class A:
    def __del__(self):
        print(666)
obj = A()      # 执行完自动执行obj所属类A的__del__方法

8.__new__

class A:
    def __init__(self):
        self.x = 1
        print("in init function")

    def __new__(cls, *args, **kwargs):
        print("in new function")
        return object.__new__(A)           # 必须要有此行代码,不然对象()只会执行__new__方法,不执行__init__方法
a = A()

# 类名()
'''
1.先触发object类的__new__方法,此方法在内存中开辟一个对象空间
2.执行__init__的方法
'''

五.单例模式

一个值只允许实例化一个对象

class A:
    __instance = None

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

    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance

obj = A("alex")
print(obj)             # <__main__.A object at 0x0000014B366A8470>
obj1 = A("wusir")
print(obj1)            # <__main__.A object at 0x0000014B366A8470>
网友评论