python类中最大的_python类高级话题

1、变量名压缩

class 语句内开头 有两个下划线,但结尾没有两个下划线的变量名会自动扩张,从而包含所在类的名称。例如:象spam类内__x这样的变量名会自动变成 _spam__x.原始的变量名会在开头家一个下划线,然后是再加上所在类的类名。这一规则适用了每个开头有两个下划线 的变量名,包括方法名称和实例属性名称。(例如:在spam类内,self.__x实例属性会变成self._spam__x)

2、方法是对象:绑定或无绑定

无绑定类方法对象: 无self

通过对类进行点号运算从而获取函数的属性,会传回无绑定方法对象,调用该方法时,必须提供实例对象作为第一个参数,在python3.0中,一个无绑定方法和一个简单函数相同。可以通过类名来调用,在python2.6中,他是一个特殊的类型,并且不提供一个实例就无法调用

绑定实例方法对象: self+函数对

通过对实例进行全运算,从而获取类的汗水属性,会传回绑定方法对象。python在绑定方法对象中自动实现实例和函数的打包,所以不用传递实例去调用该方法。

例如:

class Spam:

def doit(self,message):

print(message)

在下面代码中,会传回绑定方法对象,把实例(object1)和方法函数(spam.doit)打包起来。我们可以把这个绑定方法赋值给另外一个变量。然后像函数那样进行调用。

object1 = spam()

x = object1.doit

x('hello world')

另一方面,如果对类进行点号运算来获得doit就会获得无绑定方法对象。也就是函数对象的引用值。要调用这个类方法时,必须传入实例作为最左侧参数

例如:

object2 = Spam()

t = Spam.doit

t(object2,'howdy')

扩展一下:如果我们引用的self属性是引用类中的函数,那么相同的规则也适用于类的方法。self.method表达式是邦定方法,因为self是实例对象。

例如:

class C:

def m1(self,n):

print('m1=',n)

def m2(self,t):

x = self.m1 #这里是通过实例和方法打包,是绑定方法。

x(t)#在这里调用绑定方法不需要传入实例

print('m2=',t)

c = C()

c.m2(88)

print('#'*8)

C.m2(c,77)

print('-'*8)

class B:

def m1(self,n):

print('m1=',n)

def m2(self,t):

x = B.m1 #这里通过类来获取类中的函数,是无绑定方法对象

x(self,t)#这里使用时需要传入一个类对象。

print('m2=',t)

b = B()

B.m2(b,99)

print('@'*8)

b.m2(66)

#输出结果:

m1= 88

m2= 88

########

m1= 77

m2= 77

--------

m1= 99

m2= 99

@@@@@@@@

m1= 66

m2= 66

3、在python3.0中无绑定方法是函数

在python3.0中已经删除"无绑定方法"的概念,但是还是可以使用。在上面介绍的绑定方法,在python3.0中只当作一个简单函数来使用。简单函数不期待传递给他一个实例,非简单函数期待传递一个实例。

此外:在python3.0中不使用一个实例而调用一个方法没有问题,只要这个方法不期待一个实例,并且你通过类调用它而不是通过一个实例调用它。也就是说,只有对通过实例调用,python3.0才会向方法传递一个实例。当通过一个类调用的时候,只有在方法期待一个实例的时候,才必须手动传递一个实例。

class Selfless:

def __init__(self,data):

self.data = data

def selfless(arg1,arg2):

return arg1+arg2

def normal(self,arg1,arg2):

return self.data+arg1+arg2

x = Selfless(2)

print(x.normal(3,4))

print('-'*8)

print(Selfless.normal(x,3,4))

print('-'*8)

print(Selfless.selfless(3,4)) #在python3.0中可以通过一个类去调用这个类的普通方法,但是在python2.6中不行,会抱错。

print('-'*8)

#print(x.selfess(3,4)) 不能通过实例去调用一个类的普通方法

4、多重集成

在传统类中(默认的类,直到python3.0),属性搜索处理对所有路径深度优先 ,直到继承树的顶端,然后从左到右

在新式类(以及python.30的所有类中)属性搜索处理沿着树层级,以及更宽广优先的方式。

例如:使用__dict__列出实例属性

class Listinstance:

'''

Mix-in class that provides a formatted print() or str() of instance of via inheritance of __str__, coded here:displays instance attrs only;self is the instance of lowest class;

uses __x names to avoid clashing with client's attrs

'''

def __str__(self):

return ''%(

self.__class__.__name__,#每个实例都有一个内置的__class__属性,它引用创建 自己的类,并且每一个类都有一个__name__属性。他引用头部的名称。

id(self), #返回该对象的内存地址

self.__attrnames()

)

def __attrnames(self):

result = ''

for attr in sorted(self.__dict__):

result+='\tname %s=%s\n'%(attr,self.__dict__[attr])

return result

s = spam(12)

print(s)

#输出:

name data=12

>

例如:使用dir列出继承的所有属性

class ListInherited:

'''

Use dir() to collect both instance attrs and names

inherited from its classes; python3.0 shows more

names than 2.6 because of the implied object supperclass

in the new-style class model; getattr() fetches inherited

names not in self.__dict__;use __str__,not __repr__

or else this loops when printing bound methods

'''

def __str__(self):

return ''(self.__class_.__name,

id(self),

self.__attrnames())

def __attrnames(self):

result = ''

for attr in dir(self):

if attr[:2] == '__' and attr[-2:] == '__':

result+='\tname %s = <>'%attr

else:

result += '\tname %s=%s\n'%(attr,getattr(self,attr))

return result

例如:列出类树中的每个对象的属性

class ListTree:

'''

Mix-in that returns an __str__ trace of the entire class

tree and all its objects'attrs at and above self;

run by print(),str() returns constructed string;

uses __x attr names to void impacting clients;

uses generator expr to recurse to superclasses;

uses str.format() to make substituion clear

'''

def __str__(self):

self.__visited = {}

return '

self.__class__.__name__,

id(self),

self.__attrnames(self,0),

self.__listclass(self.__class_,4)

)

def __listclass(self,aClass,indent):

dots = '.'*indent

if aClass in self.__visited:

return '\n{0}\n'.format(

dots,

aClass.__name,

id(aClass)

)

else:

self.__visited[aClass]=True

genabove = (self.__listclass(c,indent+4) for c in aClass.__base__)

return '\n{0}\n'.format(

dots,

aClass.__name__,

id(aClass),

self.__attrnames(aClass,indent),

''.join(genabove),

dots

)

def __attrnames(self,obj,indent):

spaces = ' ' * (indent+4)

result = ''

for attr in sorted(obj.__dict__):

if attr.startwith('__') and attr.endwith('__'):

resutl +=spaces +'{0}=<>\n'.format(attr)

else:

result ++space+'{0}={1}\n'.format(attr,getattr(obj,attr))

return result

4、新式类

对于python3.0来说,所有类都是我们所谓的”新式类“,不管他们是否显示继承object.所有类都继承自object.不管显式还是隐式,所有对象都是object的实例

在python2.6及其以前版本,类必须继承自类看作是新式”object,并且获得新式类的特性。

5、新式类的变化

1)类和类型合并

类现在就是类型,并且类型现在就是类,实际上,这二者基本上是同义词。type(I)内置函数返回一个创建这个实例I的类。而不是一个通用实例类型,并且,通常是和I.__class__相同。此外,雷氏type类的实例,type可能子类化

6、__slots__

如果一个字类继承一个没有__slots__的超类,那么超类的__dict__属性总是可以访问的,使得字类的__slots__没有意义

如果一个超类定义了一个与超类相同的slots名称,超类slots定义的名称只有通过从直接超类获取其描述符才能访问

由于一个超类__slots__声明的含义受到它出现其中类的限制,所以一个字类将有一个__dict__除非他也声明了一个__slots__

通常从列出实例属性这方面来看,多数类的slots可能需要手动类树爬升、dir用法或者把slot名称当作不同的名称领域的政策

7、特性

适用条件是这个类必须继承object

class classic:

def getx(self)

return self.__x

def setx(self,data):

self.__x =data

def delx(self)

self.__x = None

x = property(getx,setx,delx,None)

8、__getattribute__方法只适用于新式类,可以让类拦截所有属性的引用,而不是局限于未定义的引用

9、静态方法和类方法

不用一个实例就可以调用 :静态方法

传递一个类而不是一个实例:类方法

10、静态方法和类方法使用实例

静态方法:

class Spam:

numInstances = 0

def __init__(self):

Spam.numInstances +=1

def printNumInstance():

print("Number of instance:",Spam.numInstances)

printNumInstance = staticmethod(printNumInstance)

a = Spam()

b = Spam()

c = Spam()

Spam.printNumInstance()

a.printNumInstance()

继承:

class Sub(Spam):

def printNumInstance():

print('extra stauff...')

Spam.printNumInstance()

printNumInstance = staticmethod(printNumInstance)

a = Sub()

b = Sub()

a.printNumInstance()

Sub.printNumInstance()

Spam.printNumInstance()

类方法

class Spam:

numInstances = 0

def __init__(self):

Spam.numInstances +=1

def printNumInstance(cls):

print("Num of instnace:", cls.numInstances)

printNumInstance = classmethod(printNumInstance)

a,b = Spam(),Spam()

a.printNumInstance()

Spam.printNumInstance()

继承方法同静态方法相同

11、装饰器和元类

例如:

class Spam:

numInstances = 0

def __init__(self):

Spam.numInstances +=1

@staticmethod

def printNumInstance():

print("Number of instance:",Spam.numInstances)

a = Spam()

b = Spam()

c = Spam()

Spam.printNumInstance()

a.printNumInstance()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值