Python进阶与拾遗5:Python中的新式类


在常用的Python面向对象编程中,几乎都是使用新式类。本篇博文向大家介绍Python中的新式类,下面开始干货。

新式类相关概念

  1. 对Python 3.0及之后的版本来说,所有的类都是“新式类”,不管是不是显式地继承自object。所有的类都继承自object,不管显式隐式,所有对象都是object的实例,包括内置类型。
  2. 对Python 2.6及其之前的版本来说,类必须继承自的类看作是“新式”object,并具有新式类的特性。任何从object或其他内置类型派生的类,会被自动视为新式类,只要一个内置类型位于超类树中的某个位置,就是一个新式类。

新式类的变化

  1. 类和类型合并。type(I)内置函数返回一个实例所创建的类,而不是一个通用的实例类型,通常和I.__class__相同。
class C: pass
class D: pass

def main():
    c = C()
    d = D()
    print(type(c))
    print(c.__class__)
    print(type(C))
    print(C.__class__)
    print(type(d))
    print(d.__class__)
    print(type(D))
    print(D.__class__)
    print(type(c) == type(d))

    l = [1, 2, 3]
    print(type(l))

    print(isinstance(c, object))
    print(isinstance(C, object))
    print(isinstance(l, object))

if __name__ == "__main__":
    main()
'''
输出:
<class '__main__.C'>
<class '__main__.C'>
<class 'type'>
<class 'type'>
<class '__main__.D'>
<class '__main__.D'>
<class 'type'>
<class 'type'>
False
<class 'list'>
True
True
True
'''
  1. 多继承的钻石模式继承搜索顺序变更。先宽度搜索,再深度搜索
class A:
    attr = 1

class B(A):
    pass

class C(A):
    attr = 2

class D(B, C):
    pass

def main():
    x = D()
    print(x.attr)


if __name__ == "__main__":
    main()
'''
输出:
2
'''
  1. 针对内置函数的属性获取。__getattr__和__getattribute__方法不再针对内置运算的隐式属性获取并运行。名称搜索从类开始,而不是从实例开始。
  2. 新增高级工具如slot,特性,描述符和__getattribute__方法。

新式类的扩展

__slots__的用法

  1. 在class语句顶层将字符串名称顺序赋值给变量__slots__,只有__slots__列表内这些变量值可以赋值为实例属性,并且不能在类的顶层空间中赋值。
  2. 在__slots__中,一般会包含__dict__,这样可以收纳__slots__中不包含的属性,也使得例如getattr和setattr这样的通用方法能够运行。
class C:
    __slots__ = ['a', 'b', '__dict__']
    # a = 1 # ValueError: 'a' in __slots__ conflicts with class variable

def main():
    X = C()
    X.a = 1
    X.b = 2
    X.c = 3
    setattr(X, 'd', 4)
    print(X.__dict__)
    print(dir(X))
    print(getattr(X, 'd'))

if __name__ == "__main__":
    main()
'''
输出:
{'c': 3, 'd': 4}
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'a', 'b', 'c', 'd']
4
'''
  1. 继承中的__slots__:
    子类继承一个没有__slots__的超类,超类的__dict__属性总是可以访问的,并且子类的__slots__无意义。如果一个类定义了与超类相同的slots名称,那么超类中的slots变量只有通过直接从超类获取描述符才能访问。如果子类中的slots包含了__dict__,那么就可以直接访问。也就是说,子类最好加上__dict__
class C:
    a = 1
    b = 2

class D(C):
    __slots__ = ['c', 'd']

def main():
    X = D()
    X.a = 1
    X.b = 2
    X.c = 3
    X.e = 5
    setattr(X, 'd', 4)
    print(X.__dict__)
    print(dir(X))
    print(getattr(X, 'd'))

if __name__ == "__main__":
    main()
'''
输出:
{'a': 1, 'b': 2, 'e': 5}
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'c', 'd', 'e']
4
'''
class C:
    __slots__ = ['c', 'd']
    a = 1
    b = 2

class D(C):
    __slots__ = ['c', 'd', '__dict__']

def main():
    X = D()
    X.c = 3
    X.d = 4
    X.f = 5
    C.c = 10
    print(X.a)
    print(C.c)
    print(X.c)
    print(X.__dict__)
    print(dir(X))


if __name__ == "__main__":
    main()
'''
输出:
1
10
3
{'f': 5}
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'a', 'b', 'c', 'd', 'f']

'''

类特性

内置函数property让新式类定义自动调用的方法,来读取或者赋值实例属性。一般都是在class顶层赋值。对属性本身的读取,会传递给property一个读取方法。

class newprops():
    def getage(self):
        return self._age
    def setage(self,value):
        self._age = value
    age = property(getage, setage, None)


def main():
    X = newprops()
    X.age = 100
    print(X.age)
    print(X._age)


if __name__ == "__main__":
    main()
'''
输出:
100
100
'''

以上,欢迎各位读者朋友提出意见或建议。

欢迎阅读笔者后续博客,各位读者朋友的支持与鼓励是我最大的动力!

written by jiong
夫人之相与,俯仰一世。
或取诸怀抱,悟言一室之内;
或因寄所托,放浪形骸之外。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python进阶之路》是一本非常值得推荐的Python进阶书籍。这本书由一位经验丰富的Python大牛所著,作者拥有超过20年的Python开发经验。这本书涵盖了许多Python进阶知识点,如元编程、动态属性、属性描述符、异步处理等。书详细列举了这些高级特性的使用方法,并讲解得非常透彻。如果你想从入门迈向进阶,这本书是必备的参考资料。 另外,《Python Cookbook》也是一本非常受欢迎的Python进阶书籍。这本书总结了大量精妙的编程技巧和实用的技术,无论你是Python新手还是老手,都会从收获很多。豆瓣评分高达9.2分,可见其受到广大读者的认可。 除了以上两本书,《Python进阶技巧》也是一本非常值得一读的进阶书籍。这本书的作者将许多代码简化成了一行,展现了Python的高级技巧。虽然有些地方可能看起来有些夸张,但它确实帮助你了解Python的特性和一些不错的功能。而且,在关键时刻,这种技巧还可以让你轻松搞定其他人需要十几行代码才能完成的任务。对于想要进阶的同学来说,这本书的阅读是非常适合的。 总而言之,《Python进阶之路》、《Python Cookbook》和《Python进阶技巧》都是非常优秀的Python进阶书籍,适合想要深入学习Python的读者。 : 引用自《Python进阶之路》 : 引用自《Python Cookbook》 : 引用自《Python进阶技巧》

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值