Python下一切皆对象,每个对象一般都有多个属性(attribute)。同样每个Python类会带有内置属性(包括数据属性和方法属性),即只要你新建了类,系统就会自动创建这些属性。这些内置的类属性一般以双下划线开头,以双下划线结尾。如下一个类
class Student():
country="china"
def __init__(self,sname,ssex):
self.name=sname
self.sex=ssex
def setage(self,age):
self.age=age
def getinfo(self):
return "my name is"+self.name+",and i'm "+ str(self.age)+" years old."
使用dir()函数看下类及其类实例有那些属性。如
>>>dir(Student)
['__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__', 'country', 'getinfo', 'setage']
>>>dir(stu)
['__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__', 'age', 'country', 'getinfo','name', 'setage', 'sex']
>>>
dir()函数会自动寻找一个对象的所有属性(对于类来说,还包括从父类中继承的属性)。因为我们这里用的是新式类,新式类继承于父类 object ,而这些我们没有写的属性,都是在 object 中定义的。如
>>>dir(object)
['__class__','__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__','__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__','__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__','__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>>
这些内置的属性可以使用点运算符像任何其他属性一样来访问。下面介绍几个比较重要的属性。
__class__
这个属性只有实例中有,它表示创建这个实例的类是哪个(一般自定义类的全名是'__main__.className')。如
>>>Student.__class__
>>>
>>>stu.__class__
>>>
__dict__
这个特殊属性用来存储对象属性,它是一个字典,其键为属性名,值为属性的值。
首先看一下类的__dict__,如
>>> Student.__dict__
mappingproxy({'__module__': '__main__', 'country':'china', '__init__': ,'setage': , 'getinfo': , '__dict__': , '__weakref__': , '__doc__': None})
>>>
再看一下,实例对象的__dict__,我们新实例化一个对象,如
>>> newstu=Student("xiao zhang","fmale")
>>>
>>> newstu.__dict__
{'name': 'xiao zhang', 'sex': 'fmale'}
>>>
可见,实例的__dict__仅存储与该实例相关的实例属性,并不包含该实例的所有有效属性,这也说明了正是因为实例的__dict__属性,每个实例的实例属性才会互不影响。。所以如果想获取一个对象所有有效属性,应使用dir()。可以说__dict__是dir()的子集,dir()包含__dict__中的属性。
类的静态函数、类函数、实例函数、类变量以及一些内置的属性都是放在类的__dict__里的。但类的__dict__并不包含其父类的属性。
>>> Student.__dict__
mappingproxy({'__module__': '__main__', 'country':'new paradise', '__init__': , 'setage': , 'getinfo': , '__dict__': , '__weakref__': , '__doc__': None})
>>>
int,list, dict等这些常用的数据类型是没有__dict__属性的。
在继承关系中,子类和父类有各自的__dict__。
__module__
类定义所在的模块(如果类位于一个导入模块mymod中,那么className.__module__等于mymod,否则就是__main__)
__doc__
类的文档字符串。一般而言,是对函数/方法/模块所实现功能的简单描述,如果没有定义则为None。但当指向具体对象时,如每个函数都是一个对象,每个函数对象都有一个__doc__的属性,函数语句中,如果第一个表达式是一个string,这个函数的__doc__就是这个string,否则__doc__是None。
class new(object):
'''whatsaying'''
deffun(self):
'''funtext'''
pass
>>> new.__doc__
'what saying'
>>> new().fun.__doc__
'fun text'
>>>
__str__&__repr__
__repr__和__str__这两个方法都是用于显示的,__str__是面向用户的,其返回值是可读性较好的字符串类型,而__repr__面向python解释器的,其返回值表示解释器内部的含义。这两个函数分别由内置的str()\print()和repr()调用。在解释器中直接输入对象时默认调用repr()函数,而print则调用str()函数。
str([object]),返回一个可以用来表示对象的可打印的友好的字符串,对字符串,返回本身。没有参数,则返回空字符串 ,对类可通过 __str__() 成员控制其行为。
要改变一个实例的字符串表示,可重新定义它的__str__()和__repr__()方法。
>>>class Person(object):
... def __init__(self, name, gender):
... self.name = name
... self.gender = gender
...
>>>p = Person('Bob', 'male')
>>>p
<__main__.Personobject at 0x2b1aa62417d0>
>>>print p
<__main__.Personobject at 0x2b1aa62417d0>
>>>
>>>class Student(Person):
... def __str__(self):
... return '(Student: %s, %s)' %(self.name, self.gender)
...
>>>p = Student('Bob', 'male')
>>>
>>>p #调用__repr__()方法
<__main__.Studentobject at 0x2b1aa62419d0>
>>>print p #调用自定义的__str__()方法
(Student:Bob, male)
>>>
repr(object),返回一个可以用来表示对象的可打印字符串,首先,尝试生成这样一个字符串,将其传给 eval()可重新生成同样的对象, 否则生成用尖括号包住的字符串,包含类型名和额外的信息(比如地址) ,一个类(class)可以通过 __repr__() 成员来控制repr()函数作用在其实例上时的行为。
一般来说,类中都应该定义__repr__()方法,而__str__()方法可选。但当可读性比准确性重要的时候,就应该考虑定义__str__()方法。如果类中没有定义__str__()方法,则默认使用__repr__()方法的结果来返回对象的字符串表示形式。
>>>class Teacher(Person):
... def __repr__(self):
... return '(Teacher: %s, %s)' %(self.name, self.gender)
...
>>>
>>>p = Teacher('Tom', 'female')
>>>p
(Teacher:Tom, female)
>>>print p
(Teacher:Tom, female)
>>>