python博客主题_Python——类的⾼级主题
介绍关于类的⼀些⾼级主题,这些是可选的,在Python应⽤程序中,不会常常遇到。
==========================================================================
slots实例
将字符串属性名称顺序赋值给特殊的__slots__类属性。就能够限制类的实例将有的合法属性集。
这个特殊属性通常是在class语句顶层内将字符串名称顺序赋值给变量__slots__⽽设置:仅仅有__slots__列表内的这些变量名可赋值为实例属性。⽽实例属性名必须在引⽤前赋值,即使是列在__slots__中也是这样。看下述样例:
>>> class limiter(object):
__slots__ = ['age','name','job']
>>> x = limiter()
>>> x.age
Traceback (most recent call last):
File "", line 1, in
x.age
AttributeError: age
>>> x.age = 40
>>> x.age
40
>>> x.ape = 1000
Traceback (most recent call last):
File "", line 1, in
x.ape = 1000
AttributeError: 'limiter' object has no attribute 'ape'假设创建了⾮常多实例⽽且仅仅有⼏个属性是必需的话。那么为每⼀个实例对象分配⼀个命名空间字典可能在内存⽅⾯的代价过于昂贵。要节省空间和运⾏速度,slot属性能够顺序存储以供⾼速查,⽽不是为每⼀个实例分配⼀个字典。
-------------------------------------------------------------------------------------------------------------------------------------
Slot和通⽤代码
实际上。有些带有slots的实例或许根本就没有__dict__属性字典。所以在有些程序中要使⽤⽐__dict__更为存储中⽴的⼯具,⽐如
getattr、setattr和dir内置函数。
>>> class C:
__slots__ = ['a','b']
怨苍天变了心原唱>>> X = C()
>>> X.a = 1
>>> X.a
1
Traceback (most recent call last):
File "", line 1, in
X.__dict__
AttributeError: 'C' object has no attribute '__dict__'
>>> getattr(X,'a')
1
>>> setattr(X,'b',2)
>>> X.b
谜语及答案2
>>> 'a' in dir(X)
True
>>> 'b' in dir(X)
True没有属性命名空间字典,不可能给不是slots列表中名称的实例来分配新的名称,然⽽,通过在__slots__中包括__dict__仍然能够容纳额外的属性,从⽽考虑到⼀个属性空间字典的须要。在这个样例中。两种机制都⽤到了,可是,getattr这种通⽤⼯具同意我们将它们当做单独⼀组属性对待:
我国哪座城市素有日光城之称>>> class D:
__slots__ = ['a','b','__dict__']
c = 3
def __init__(self):
self.d = 4
>>> X = D()
>>> X.d
4
>>> X.__dict__
{'d': 4}
>>> X.__slots__
['a', 'b', '__dict__']
>>> X.c
三峡古诗3
>>> X.a
Traceback (most recent call last):
File "", line 1, in
X.a
AttributeError: a
>>> getattr(X,'a'),getattr(X,'c'),getattr(X,'d')
(1, 3, 4)==========================================================================
类特性
有⼀种称为特性(property)的机制,提供还有⼀种⽅式让类定义⾃⼰主动调⽤的⽅法,来读取或赋值实例属性。
【特性和slots都是基于属性描写叙述器的新概念】
简⽽⾔之,特性是⼀种对象,赋值给类属性名称。特性的产⽣是以三种⽅法(获得、设置以及删除运算的处理器)以及通过⽂档字符串调⽤内置函数property。假设不论什么參数以None传递或者省略。该运算就不能⽀持。
特性⼀般都是在class语句顶层赋值【⽐如,name = property(...)】。这样赋值时。对类属性本⾝的读取(⽐如。obj.name),就会⾃⼰主动传给property的⼀个读取⽅法。例如以下例:
>>> class new():
def getage(self):
return 40
age = property(getage,None,None,None) # get,set,del,docs
>>> x = new()
和平精英武器排名>>> x.age
40
>>> x.name
Traceback (most recent call last):
File "", line 1, in
豹纹外套x.name
AttributeError: 'new' object has no attribute 'name'特性⽐传统技术执⾏起来更快。
⽐如,当我们新增属性赋值运算⽀持时,特性就变得更有吸引⼒:输⼊的代码更少,对我们不希望动态计算的属性进⾏赋值运算时,不会发⽣额外的⽅法调⽤。
>>> class new():
def getage(self):
return 40
def setage(self,value):
print('set age:',value)
self._age = value
age = property(getage,setage,None,None)
>>> x = new()
>>> x.age
40
>>> x.age = 42
>>> x.age
40
>>> x._age
42
>>> x.job = 'trainer'
>>> x.job
'trainer'==========================================================================
__getattribute__和描写叙述符
__getattribute__能够让类拦截全部属性的引⽤。⽽不局限于没有定义的引⽤(假设__getattr__)。
除了特性和运算符重载⽅法,Python⽀持属性描写叙述符的概念——带有__get__和__set__⽅法的类,分配给类属性⽽且由实例继承,这拦截了对特定属性的读取和写⼊訪问。描写叙述符在某种意义上是特性的⼀种更加通⽤的形式。
关于特性、__getattribute__和描写叙述符这些⾼级话题将在兴许逐步介绍。
==========================================================================
静态⽅法
类⽅法通常在其第⼀个參数中传递⼀个实例对象。以充当⽅法调⽤的⼀个隐式主体。有时候。程序须要处理与类⽽不是与实例相关的数据,也就是我们须要⼀个类中的⽅法不仅不传递并且也不期待⼀个self实例參数。
Python通过【静态⽅法】的概念来⽀持这种⽬标——嵌套在⼀个类中的没有self參数的简单函数。
⽐如。如果我们想使⽤类属性去计算从⼀个类产⽣了多少实例。我们能够把⼀个计数器存储为类属性。每次创建⼀个新的实例的时候。构造函数都会对计数器加1。⽽且,有⼀个显⽰计数器值的⽅法。【记住,类属性是由全部实例共享的】:
>>> class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances += 1
def printNumInstances():
print('Number of instances created:',Spam.numInstances)printNumInstances⽅法旨在处理类数据⽽不是实例数据——它是关于全部实例的,⽽不是某个特定的实例。因此,我们想要不必传递⼀个实例就能够调⽤它。
实际上,我们不想⽣成⼀个实例来获取实例的数⽬。由于这本⾝就会改变我们想要获取的实例的数⽬。
换句话说:我们想要⼀个⽆self的静态⽅法。
我们能够看⼀下測试结果:
>>> a = Spam()
>>> b = Spam()
>>> c = Spam()
>>> Spam.printNumInstances()
Number of instances created: 3
>>> a.printNumInstances()
Traceback (most recent call last):
File "", line 1, in
a.printNumInstances()
TypeError: printNumInstances() takes 0 positional arguments but 1 was given能够看到,我们通过类调⽤⽆self⽅法执⾏成功。⽽通过实例调⽤⽆self⽅法出错了,由于參数不正确。通过⼀个实例调⽤⽅法。这个实例会⾃⼰主动传递给⽅法的第⼀个參数中,可是这个⽆self⽅法并不存在參数来接收它。
假设你可以坚持仅仅通过类调⽤⽆self⽅法。那么事实上你已经有了⼀个静态⽅法了。然⽽假设你还想通过实例调⽤,那么就须要採取其它设计,或者把这个⽅案标记为特殊的。
-------------------------------------------------------------------------------------------------------------------------------------
使⽤静态⽅法
要将这个⽆self⽅法标记为静态⽅法。须要调⽤内置函数staticmethod。例如以下:
>>> class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances += 1
def printNumInstances():
print('Number of instances created:',Spam.numInstances)
printNumInstances = staticmethod(printNumInstances) # staticmethod
>>> a = Spam()
>>> b = Spam()
>>> c = Spam()
>>> a.printNumInstances()
Number of instances created: 3静态⽅法对于处理⼀个类本地的数据来说是更好的解决⽅式。
==========================================================================
装饰器和元类:初识
上边提到的staticmethod可能⽐較奇怪。所以新增了⼀个功能,要让这个运算变得简单。【函数装饰器】提供了⼀种⽅式,替函数明⽩了特定的运算模式。也就是将函数包裹了还有⼀层,在还有⼀函数的逻辑内实现。
函数装饰器变成了通⽤的⼯具:除了静态⽅法使⽤⽅法外。也可⽤于新增多种逻辑的函数。⽐如,能够⽤来记录函数调⽤的信息和在出错时检查传⼊的參数类型等
Python提供了⼀下内置的函数装饰器,来做⼀些运算,⽐如。标识静态⽅法,可是我们也能够编写⾃⼰的随意装饰器。尽管不限于使⽤类,但⽤户定义的函数装饰器通常也写成类,把原始函数和其它数据当成状态信息。
-------------------------------------------------------------------------------------------------------------------------------------
函数装饰器基础
从语法上讲,函数装饰器是它后边的函数的执⾏时的声明。
函数装饰器是写成⼀⾏,就在定义函数或⽅法的def语句之前,并且由@符号、后⾯跟着所谓的元函数组成:也就是管理还有⼀函数的函数。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论