BrightXiong 发表于 2023-4-3 22:42:51

类和对象-type函数

>>> # 与isinstance()函数相似,type()函数通常用于检测对象的类型,返回对象相应的类。
        由于Python万物的奇点正是type,封神般存在的type()函数所能做的也远不止此!
        它可以根据传入的三个参数,返回一个新的类型(type对象),三个参数分别用于指定新类的名字(字符串)、父类(元组)、属性与方法(字典)。
        type()函数“造物者”的称号也便由此而来!
        对象的__class__属性用于查看该对象的类型,类的__bases__属性用于查看该类的父类。
        __init_subclass__()是Python3.6新增的类方法,用于加强父类对子类的管理。
        子类的属性会被定义了__init_subclass__()的父类的属性所覆盖
        当我们使用type()函数创造新类时,其第四个可选收集参数将被依次传递给父类的__init_subclass__()方法

>>> # 检测对象类型推荐使用isinstance()函数更合适,因为其会考虑到子类的情况
>>> print(int)
<class 'int'>
>>> print(float)
<class 'float'>
>>> print(set)
<class 'set'>
>>> print(type('1') is str)
True
>>> print(type(250)('520'))
520
>>> print(type(type(250)('520')))
<class 'int'>

>>> # type(250)('520')相当于int('520')
>>> print(type([])('fishc'))
['f', 'i', 's', 'h', 'c']
>>> print(type({}).fromkeys('python', 250))
{'p': 250, 'y': 250, 't': 250, 'h': 250, 'o': 250, 'n': 250}
>>> class C:
...         def __init__(self, x):
...                 self.x = x
...
>>> c = C(250)
>>> print(c)
<__main__.C object at 0x0160E370>
>>> print(type(c))
<class '__main__.C'>
>>> d = type(c)
>>> print(d)
<class '__main__.C'>
>>> d = type(c)(520)
>>> print(d)
<__main__.C object at 0x0160E250>
>>> print(d.__class__)
<class '__main__.C'>
>>> print(type(c))
<class '__main__.C'>
>>> print(type(C))
<class 'type'>
>>> print(type(type))
<class 'type'>

>>> # type()就是python万物的起点:python万物皆对象,包括生成对象的类自身也是对象,其是由type()生成而来的对象,而type()本身也是自己的对象

>>> # type()第二种用法:根据传入的三个参数返回一个新的type对象
>>> class C:
...         pass
...
>>> C = type('C', (), {}) # 参数一name指定类名;参数二base指定父类,用元组收集;参数三dict指定属性和方法,用字典收集
>>> c = C()
>>> print(c.__class__)
<class '__main__.C'>
>>> print(C.__bases__)
(<class 'object'>,)
>>> D = type('D', (C,), {})
>>> print(D.__bases__)
(<class '__main__.C'>,)
>>> E = type('E', (C,), dict(x=250, y=520))
>>> print(E.__dict__)
{'x': 250, 'y': 520, '__module__': '__main__', '__doc__': None}

>>> # 创建方法
>>> def func(self, name='fishc'):
...         print(f'hello {name}')
...
>>> F = type('F', (), dict(say_hi=func))
>>> f = F()
>>> f.say_hi()
hello fishc
>>> f.say_hi('python')
hello python
>>> # 第四个参数(可选)kwds收集参数:当且仅当需要时,该收集参数将被传递给适当的元类机制(通常为__init_subclass__)
>>> # __init_subclass__()作用:加强父类对子类的管理
>>> class C:
...         def __init__subclass__(cls):
...                 print('dad love you')
...                 cls.x = 520
...
>>> class D(C):
...         x = 250
...
>>> # dad loves you
# 子类D定义完成后,父类C就会触发__init_subclass__()方法
>>> >>>
>>> print(D.x)
250
>>> # 在类定义完成后触发,所以子类的属性被覆盖
>>> class C:
...         def __init__subclass_(cls, value):
...                 print('dad loves you')
...                 cls.x = value
...
>>> class D(C, value=520):
...         x = 250
...
>>> print(D.x)
520

>>> # 当使用type()函数构造想class D这种继承了定义过__init_subclass__()的父类时,
        如果需要给__init_subclass__()传递参数(如value),就可以通过第四个参数接力
>>> D = type('D', (C,), dict(x=250), value=520)
# dad loves you
print(D.x)
# 520

# 第四个参数是收集参数
class C:
    def __init_subclass__(cls, value1, value2):
      print('dad loves you')
      cls.x = value1
      cls.y = value2

D = type('D', (C,), dict(x=250), value1=520, value2=666)
# dad loves you
print(D.x)#520
print(D.y)#666

class C:
    def __init_subclass__(cls, **kwargs):
      print('dad loves you')
      cls.x = list(kwargs.values())
      cls.y = list(kwargs.values())

D = type('D', (C,), dict(x=250), value1=520, value2=666)
# dad loves you
print(D.x)#520
print(D.y)#666
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: D.__init_subclass__() takes no keyword arguments
>>> 250
>> dad loves you
>>> 520
>>> 666
>>> dad loves you
>>> 520
>>> 666
页: [1]
查看完整版本: 类和对象-type函数