我们了解了类的三大特性后,就可以对类进行进一步的了解了。(其实就是了解各种命令)
1)获取对象信息
我们通常对一个对象的那些东西感兴趣呢?先想一下对象有什么内容吧。对象通常包含,属性和方法。我们首先想知道这个对象到底有什么属性,是什么数据类型。
(1)type
type的用法如下:
print (type(123))print (type('abc'))print (type(None))
输出结果:
还可以这么用:
print (type(123)==type(567))print (type(123)==int)print (type(123)==str)
输出:
TrueTrueFalse
上面都是基本数据类型,要是我们想判断是不是函数怎么办?这里我们用到了types模块。示例如下:
import typesdef func(self): passprint(types.FunctionType==type(func))
输出:True
但是如果我们这么写:
import typesdef func(self): passprint(types.FunctionType==func)
输出:False
为什么呢?因为,func是一个函数变量名,是一个地址,16进制数。所以失败。
要是我们这么写呢?
print(type(func))
输出结果:
事实证明,不要太迷信教材,资料,type也是可以判断函数的。
(2)isinstance
我们要获得继承的关系,用isinstance,我们可以之前强调过,子类可以是父类,父类不可以是子类。
我们现在验证一下,示例代码如下:
a=Dog()b=Animal()print (isinstance(a,Animal))
输出结果如下:
True
第一句是对的。我们继续:
a=Dog()b=Animal()print (isinstance(b,Dog))
输出结果如下:
False
另外,isinstance还可以判断该数据是不是若干种类型的一种。示例如下:
a=[1,2,3,4]print (isinstance(a,(list,tuple)))
输出如下:
True(3)获取并操作属性
这里我们可以,使用dir()函数来进行操作。dir()函数用来输出对象的所有数据和属性,示例如下:
class Myobject(object): def __init__(self): self.x=0 def power(self): return self.x*self.xh=Myobject()print (dir(h))
输出结果如下:
['__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__','__str__', '__subclasshook__', '__weakref__', 'power', 'x']
我们可以看到有好多,好多。显然这个函数是不实用的。
我们如果想要获得,判断,添加某一个属性,可以用getattr(),hasattr(),setattr()函数。示例如下:
class Myobject(object): def __init__(self): self.x=0 def power(self): return self.x*self.xh=Myobject()print (hasattr(h,'x'))print (hasattr(h,'y'))setattr(h,'y',5)print (hasattr(h,'y'))
输出结果如下:
TrueFalseTrue
另外,getattr()函数可以设定缺省值(default值),得到失败时,可以返回缺省值。
我们在之前知道__xxx__类数据,都是特殊用途变量,最好不要乱动,我们这里其实可以定制,自己的类让它具有某种特定的方法,示例代码如下:
class Myobject(object): def __init__(self): self.x=0 def __len__(self): return 3print(len(h))
输出结果为:
32)实例属性和类属性
我们前面所提到的所有属性都是针对实例而言的,因为在定义时是将属性绑定到self这个形参上面。其实类也是有属性的,我们可以在类里面直接定义,示例如下:
class MyClass(object): attr='strong' def __init__(self): self.x=0print(MyClass.attr)
我们在这里为MyClass定义了一个attr属性,属性的值为‘strong’。输出结果如下:
strong
实际上如果我们在这里,为实例再绑定一个attr属性,看看会是什么样的。示例代码如下:
class MyClass(object): attr='strong' def __init__(self): self.x=0 self.attr='high'h=MyClass()print(MyClass.attr)print(h.attr)
输出结果如下:
stronghigh
我们可以看到,类属性和实例属性互不影响。
再看看,如果我们把实例属性删掉,但是依然访问会有什么结果:
#!/usr/bin/env python3# -*- coding: utf-8 -*-class MyClass(object): attr='strong' def __init__(self): self.x=0h=MyClass()print(MyClass.attr)print(h.attr)
输出结果如下:
strongstrong
很明显,实例属性自动找到类属性上了。
两个程序一对比,可以得出结论,实例属性的优先级高于类属性优先级!
所以不要让类属性名和实例属性名重复。
希望有志同道合的小伙伴关注我的公众平台,欢迎您的批评指正。
领取专属 10元无门槛券
私享最新 技术干货