我们了解了类的三大特性后,就可以对类进行进一步的了解了。(其实就是了解各种命令)


1)获取对象信息

我们通常对一个对象的那些东西感兴趣呢?先想一下对象有什么内容吧。对象通常包含,属性和方法。我们首先想知道这个对象到底有什么属性,是什么数据类型。

(1)type

type的用法如下:

print (type(123))
print (type('abc'))
print (type(None))

输出结果:

<class 'int'>
<class 'str'>
<class 'NoneType'>

还可以这么用:

print (type(123)==type(567))
print (type(123)==int)
print (type(123)==str)

输出:

True
True
False

上面都是基本数据类型,要是我们想判断是不是函数怎么办?这里我们用到了types模块。示例如下:

import types
def func(self):
    pass
print(types.FunctionType==type(func))

输出:True

但是如果我们这么写:

import types
def func(self):
    pass
print(types.FunctionType==func)

输出:False

为什么呢?因为,func是一个函数变量名,是一个地址,16进制数。所以失败。

要是我们这么写呢?

print(type(func))

输出结果:

<class 'function'>

事实证明,不要太迷信教材,资料,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.x
h=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.x
h=Myobject()
print (hasattr(h,'x'))
print (hasattr(h,'y'))
setattr(h,'y',5)
print (hasattr(h,'y'))

输出结果如下:

True
False
True

另外,getattr()函数可以设定缺省值(default值),得到失败时,可以返回缺省值。

我们在之前知道__xxx__类数据,都是特殊用途变量,最好不要乱动,我们这里其实可以定制,自己的类让它具有某种特定的方法,示例代码如下:

class Myobject(object):
    def __init__(self):
        self.x=0
    def __len__(self):
        return 3
print(len(h))

输出结果为:

3
2)实例属性和类属性

我们前面所提到的所有属性都是针对实例而言的,因为在定义时是将属性绑定到self这个形参上面。其实类也是有属性的,我们可以在类里面直接定义,示例如下:

class MyClass(object):
    attr='strong'
    def __init__(self):
        self.x=0
print(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)

输出结果如下:

strong
high


python输出对象的属性和值 python输出类的属性_类属性


我们可以看到,类属性和实例属性互不影响。

再看看,如果我们把实例属性删掉,但是依然访问会有什么结果:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class MyClass(object):
    attr='strong'
    def __init__(self):
        self.x=0
h=MyClass()
print(MyClass.attr)
print(h.attr)

输出结果如下:

strong
strong

python输出对象的属性和值 python输出类的属性_bc_02

很明显,实例属性自动找到类属性上了。

两个程序一对比,可以得出结论,实例属性的优先级高于类属性优先级!

所以不要让类属性名和实例属性名重复。