不管是__len__()还是__getitem__()函数都是针对类来进行操作
1. __len__():
首先__len__()
的作用是返回容器中元素的个数,要想针对类的对象实例使len()
函数成功执行,必须要在类中定义__len__()。
class CountList:
def __init__ (self,*args):
self.values=[x for x in args]
self.count={}.fromkeys(range(len(self.values)),0)
def len(self):
return len(self.values)
def __getitem__(self.key):
self.count[key]+=1
return self.values[key]
c1 = CountList(1,3,5,7,9)
如果查询:c1.values ,将会得到:[1,3,5, 7,9]
如果查询:c1.count,将会得到:{0: 0, 1: 0, 2: 0, 3: 0, 4:0}
如果查询:len(c1),将会得到:5
如果查询:len(c1.values),将会得到:5
如果没有定义__len__(),那么输入len(c1)会提示出错,显然错误原因是因为CountList类中并没有len()的定义。因为len()必须接收一个具体的实例化对象的属性,如果改成len(c1.values)也能成功执行!
对于类而言,len()函数是没有办法直接计算类的长度的,因为在类中包含着众多的属性以及方法,是一种抽象的实体。如果在类中没有定义__len__()方法来指明程序到底该计算哪个属性的长度时,在终端我们必须采用len(对象.属性)才能得到我们想要的结果。如果终端直接采用len(对象)的方法,显然程序会报错,提示类并没有len()方法。类不同于字符串、元组、列表、字典等数据类型,对于后者,它们是实实在在能通过len()方法直接计算出长度,是具体的实体。
但是就封装性而言,还是定义__len__()比较好,因为用户无需知道具体的属性是什么,只需要一个实例化对象即可。如果属性是私有的,那么无疑定义__len__()是最好的办法。
2.__getitem__():
凡是在类中定义了这个__getitem__ 方法,那么它的实例对象(假定为p),可以像这样
p[key] 取值,当实例对象做p[key] 运算时,会调用类中的方法__getitem__。__getitem __可以让对象实现迭代功能,这样可以不断的调用数据。
class Animal:
def __init__(self, animal_list):
self.animals_name = animal_list
def __getitem__(self, index):
return self.animals_name[index]
animals = Animal(["dog","cat","fish"])
for animal in animals:
print(animal)
输出:
dog
cat
fish
一般如果想使用索引访问元素时,就可以在类中定义这个方法(__getitem__(self, key) )。
一般这样用:
1:
class DataBase:
'''Python 3 中的类'''
def __init__(self, id, address):
'''初始化方法'''
self.id = id
self.address = address
self.d = {self.id: 1,
self.address: "192.168.1.1",
}
def __getitem__(self, key):
# self.__dict__.get(key, "100")
return self.d.get(key, "default")#返回指定键的值,如果键不在字典中返回默认值 None 或者设置的默认值
data = DataBase(1, "192.168.2.11")
print(data["hi"])
print(data[data.id])
输出:
default
1
2:还可以用在对象的迭代上
class STgetitem:
def __init__(self, text):
self.text = text
def __getitem__(self, index):
result = self.text[index].upper()
return result
p = STgetitem("Python")
print(p[0])
print("------------------------")
for char in p:
print(char)
输出:
P
Y
T
H
O
N
或者
class pe():
def __init__(self):
self.lis = [1, 2, 3]
def __getitem__(self, itm):
return self.lis[itm]
p = pe()
for i in p:
print(i)
输出:
1
2
3
3.__dict__属性的相关介绍:
在 Python 类的内部,无论是类属性还是实例属性,都是以字典的形式进行存储的,其中属性名作为键,而值作为该键对应的值。
为了方便用户查看类中包含哪些属性,Python 类提供了 __dict__ 属性。需要注意的一点是,该属性可以用类名或者类的实例对象来调用,用类名直接调用 __dict__,会输出该由类中所有类属性组成的字典;而使用类的实例对象调用 __dict__,会输出由类中所有实例属性组成的字典。
class CLanguage:
a = 1
b = 2
def __init__ (self):
self.name = "C语言中文网"
self.add = "http://c.biancheng.net"
#通过类名调用__dict__
print(CLanguage.__dict__)
#通过类实例对象调用 __dict__
clangs = CLanguage()
print(clangs.__dict__)
结果:
{'__module__': '__main__', 'a': 1, 'b': 2, '__init__': <function CLanguage.__init__ at 0x0000022C69833E18>, '__dict__': <attribute '__dict__' of 'CLanguage' objects>, '__weakref__': <attribute '__weakref__' of 'CLanguage' objects>, '__doc__': None}
{'name': 'C语言中文网', 'add': 'http://c.biancheng.net'}
不仅如此,对于具有继承关系的父类和子类来说,父类有自己的 __dict__,同样子类也有自己的 __dict__,它不会包含父类的 __dict__。例如:
class CLanguage:
a = 1
b = 2
def __init__ (self):
self.name = "C语言中文网"
self.add = "http://c.biancheng.net"
class CL(CLanguage):
c = 1
d = 2
def __init__ (self):
self.na = "Python教程"
self.ad = "http://c.biancheng.net/python"
#父类名调用__dict__
print(CLanguage.__dict__)
#子类名调用__dict__
print(CL.__dict__)
#父类实例对象调用 __dict__
clangs = CLanguage()
print(clangs.__dict__)
#子类实例对象调用 __dict__
cl = CL()
print(cl.__dict__)
结果为:
{'__module__': '__main__', 'a': 1, 'b': 2, '__init__': <function CLanguage.__init__ at 0x000001721A853E18>, '__dict__': <attribute '__dict__' of 'CLanguage' objects>, '__weakref__': <attribute '__weakref__' of 'CLanguage' objects>, '__doc__': None}
{'__module__': '__main__', 'c': 1, 'd': 2, '__init__': <function CL.__init__ at 0x000001721CD15510>, '__doc__': None}
{'name': 'C语言中文网', 'add': 'http://c.biancheng.net'}
{'na': 'Python教程', 'ad': 'http://c.biancheng.net/python'}
显然,通过子类直接调用的 __dict__ 中,并没有包含父类中的 a 和 b 类属性;同样,通过子类对象调用的 __dict__,也没有包含父类对象拥有的 name 和 add 实例属性。
除此之外,借助由类实例对象调用 __dict__ 属性获取的字典,可以使用字典的方式对其中实例属性的值进行修改,例如:
class CLanguage:
a = "aaa"
b = 2
def __init__ (self):
self.name = "C语言中文网"
self.add = "http://c.biancheng.net"
#通过类实例对象调用 __dict__
clangs = CLanguage()
print(clangs.__dict__)
clangs.__dict__['name'] = "Python教程"
print(clangs.name)
程序运行结果为:
{'name': 'C语言中文网', 'add': 'http://c.biancheng.net'}
Python教程