python中除了可以使用内建的类型,如list,tuple,dict,还可以创建自己的对象来实现像这些内建类型的访问,不过需要在定义类的时候对一些魔法方法逐一实现。
如下:
- class DictDemo:
- def __init__(self,key,value):
- self.dict = {}
- self.dict[key] = value
- def __getitem__(self,key):
- return self.dict[key]
- def __setitem__(self,key,value):
- self.dict[key] = value
- dictDemo = DictDemo('key0','value0')
- print(dictDemo['key0']) #value0
- dictDemo['key1'] = 'value1'
- print(dictDemo['key1']) #value1
class DictDemo:
def __init__(self,key,value):
self.dict = {}
self.dict[key] = value
def __getitem__(self,key):
return self.dict[key]
def __setitem__(self,key,value):
self.dict[key] = value
dictDemo = DictDemo('key0','value0')
print(dictDemo['key0']) #value0
dictDemo['key1'] = 'value1'
print(dictDemo['key1']) #value1
上面的对象就相当于自己创建了一个内建类型相似的字典,当实例中有类似字典的操作的时候
比如:
- dictDemo1 = {"key0":"value0"}
- print(dictDemo1["key0"]) #value0
dictDemo1 = {"key0":"value0"}
print(dictDemo1["key0"]) #value0
实例dictDemo["key0"]就类似上面的的操作,则会自动调用类中定义的方法__getitem__,输出在该方法返回的值
再看看dictDemo["key1"] = "value1",就是字典的操作,会自动调用类中定义的方法__setitem__,来设置相应的值
还有一个__del__,就是当我们要删除一个元素的时候调用(魔法方法会自动调用)
__len__ 如下:
当要使用内建函数len(),而参数是DictDemo的实例的时候,那一定要实现类型中的__len__()方法
- class DictDemo:
- def __init__(self,key,value):
- self.dict = {}
- self.dict[key] = value
- def __getitem__(self,key):
- return self.dict[key]
- def __setitem__(self,key,value):
- self.dict[key] = value
- def __len__(self):
- return len(self.dict)
- dictDemo = DictDemo('key0','value0')
- print(dictDemo['key0']) #value0
- dictDemo['key1'] = 'value1'
- print(dictDemo['key1']) #value1
- print(len(dictDemo)) #2
class DictDemo:
def __init__(self,key,value):
self.dict = {}
self.dict[key] = value
def __getitem__(self,key):
return self.dict[key]
def __setitem__(self,key,value):
self.dict[key] = value
def __len__(self):
return len(self.dict)
dictDemo = DictDemo('key0','value0')
print(dictDemo['key0']) #value0
dictDemo['key1'] = 'value1'
print(dictDemo['key1']) #value1
print(len(dictDemo)) #2
无用的缺省实现
这一点令人非常惊奇,因为Python的缺省设置通常都相对比较有用。然而,在这种情况下,__repr__的缺少实现表现为如下的代码:
return"%s(%r)"%(self.__class__,self.__dict__)
这样是非常危险的(如果对象之前相互引用很容易地就进入无限递归)。所以Python不会起作用。注意有一个缺省实现的情况:如果定义了__repr__,但没有定义__str__,对象将表现为__str__=__repr__。
用简单的术语来说,这意味着:几乎你实现的所有对象都应该有一个用于理解对象的__repr__函数。实现__str__是可选的:如果你需要一个看起来较好的打印功能(比如用于产生报表).
Python repr() 或str() 函数
Python 有办法将任意值转为字符串:将它传入repr() 或str() 函数。
repr()与反引号操作符``做的是完全一样的事情;
如下例:
>>> class D(object): ... def __str__(self): ... return "a __str__" ... def __repr__(self): ... return "a __repr__" ... >>> dr = D() >>> print dr a __str__ >>> dr a __repr__ >>> "%s" % dr 'a __str__' >>> "%r" % dr 'a __repr__'
为什么有了repr()还需要``?
Python中,有的操作符和函数是做同样的事情,原因是某些场合下函数会比操作符更适合使用,比如函数对象可作为参数传递。双星号(**)乘方运算和pow()内建函数都返回x的y次方.
repr(x)的功能也可以用`x`实现(注意, `是反引号,而不是单引号),例如:
- >>> temp = 42L
- >>> print "The temperature is " + `temp`
- The temperature is 42L
- >>>
简而言之,str,repr和反引号是将Python值转换为字符串的3种方法。函数str让
字符串更易于阅读,而repr(和反引号)则把结果字符串转换为合法的Python表达
式。
>>> print repr("Hello world")
'Hello world'
>>> print str("Hello world")
Hello world
>>> temp = 12
>>> print "test " + temp
Traceback (most recent call last):
File "<pyshell#35>", line 1, in <module>
print "test " + temp
TypeError: cannot concatenate 'str' and 'int' objects
>>> print "test " + repr(temp) #也可以用反引号将temp括起来
test 12