类属性和实例属性

类属性可以通过dir()函数和__dict__函数进行查询

dir()函数返回对象属性的一个名字列表,而__dict__返回的是一个字典,键(key)是属性名。

在看下面的例子

class MyObject():
    def __init__(self):
        self.x = 9      #init函数用于初始化,用于赋值或者添加属性
    def __le__(self):   #__le__是属性的一部分
        return 100
    def power(self):
        return self.x*self.x

p = Myobject() dir(Myobject)  #可以看到类作为对象拥有的属性。
dir(Myobject()) #可以看到实例作为对象拥有的属性。

print(p.__class__) #实例p所属类 <class '__main__.MyObject'>
print(p.__class__.__name__)   #MyObject
print(MyObject.__class__) #类Myobject所属类 <class 'type'>
print(MyObject.__class__.__name__) #type
print(type(MyObject)) #创建类,就是创建一种类型 <class 'type'>
print(type(MyObject())) #实例的类型,是对应的类 <class '__main__.MyObject'>
print(MyObject.__dict__) #可以看到所有的类的特殊属性(包括模块名、方法和数值)和存储值 {'__module__': '__main__', '__init__': <function MyObject.__init__ at 0x005B48A0... ... >
print(MyObject().__dict__)    #可以看到实例的属性,只有数据值  {'x': 9}
print(MyObject.__init__)    #<function MyObject.__init__ at 0x027848A0>
print(MyObject().__init__)  #<bound method MyObject.__init__ of <__main__.MyObject object at 0x02780810>>
print(MyObject().__init__()) #执行以后没有返回值,所以是None
print(getattr(MyObject(),'__eq__'))     #实例的属性'__eq__’的值  <method-wrapper '__eq__' of MyObject object at 0x02780770>
print(MyObject().__eq__)    #同上
print(getattr(MyObject(),'x'))      #得到属性
print(MyObject().__le__)   #返回属性值,是一种方法,<bound method MyObject.__le__ of <__main__.MyObject object at 0x02780610>>
print(MyObject().__le__())  #返回方法值
print('\d')
print(hasattr(MyObject(),'power'))    #判断实例中是否有这个属性
print(hasattr(MyObject,'power'))  #判断类中有没有这个属性
print(MyObject.power)
print(MyObject().power)

下面例子可以看清类属性和实例属性的区别:

class ObjectCreator():
    count = 0

    def __init__(self):
        ObjectCreator.count +=1
        self.count=8

print(ObjectCreator().count)
print(ObjectCreator.count)

运行结果为:

8
1

 再看一个例子:

class C():
    version = 1.2
    x={2003:'peo2'}

c=C()

print(C.version)    #   1.2
print(c.version)   #实例中没有version,访问会失败,但是Python首先会在实例中搜索version,然后是类,在就是继承树种的基类
c.version = 1.3     #建立了一个实例属性
print(C.version)     #  1.2
print(C.x)
c.x[2004]='SDFS2'   #只是搜索到了C.x,类属性可以更改,所以这一步没有建立实例属性!!!
print(C.x)   #{2003: 'peo2', 2004: 'SDFS2'}
c.x={2004:'SDFS2'}  #建立了实例属性
print(C.x)  

 

我们定义一个类:

class P1():
    def __init__(self, name):
        self.name = name
        pass
    def change(self):
        self.name = 'xuan'

A=P1('wang')
B=P1('zi')

print(A.name)
A.change()
print(A.name)
print(A.__dict__)

输出结果

wang
xuan
{'name': 'xuan'}

对象中的方法在没有实例的情况下不能被调用,只要在有实例的情况才能被调用!

 

我们看一件有意思的事情。

class P1():
    def __init__(self, name):
        self.name = name
        pass

class P2(P1):
    A=P1('wang')   #定义类属性!!
    B=P1('zi')

i=P2.A     #类属性
print(i)
print(i.name)
print(P2.__dict__)
print(P2.__dict__['A'])
b=P2.__dict__['A']
print(b)
print(P2.__dict__['A'].name) ##!!!
print(b.name)

输出结果是:

<__main__.P1 object at 0x01EB0290>

wang   #!!!
{'__module__': '__main__', 'A': <__main__.P1 object at 0x01E50290>, 'B': <__main__.P1 object at 0x01E50390>, '__doc__': None}
<__main__.P1 object at 0x01E50290>
<__main__.P1 object at 0x01E50290>
wang
wang

 我们要用下面,就会报错

class P1():
    def __init__(self, name):
        self.name = name
        pass

class P2(P1):
    A=P1('wang')
    B=P1('zi')

i=P2.A
print(i)    # 结果为:<__main__.P1 object at 0x00620290>
print(<__main__.P1 object at 0x00620290>.name)

所以我们无法直接利用类属性中存储的值,我们可以将它赋值给另一个变量,然后就可以利用这个变量了。

 

posted on 2017-01-14 14:04  wzxds02  阅读(3560)  评论(0编辑  收藏  举报

导航