前言:
- 一般情况下,我们使用对象.__dict__的方式只能拿到该对象所对应的类里的实例变量,我们无法拿到该类的类变量。
正常情况下,我们使用{key:value}创建字典,但我们还可以使用dict(key1=value1, key2=value2,…)创建字典。但是我们在将一个对象直接传给dict将会产生一个什么样的情况呢,看个例子:
class Test:
name = 'Lily'
age = 18
def __init__(self, gender, works, year):
self.gender = gender
self.works = works
self.year = year
t = Test('F', 'Student', 4)
print(dict(t))
上面的例子将会报出:TypeError: ‘Test’ object is not iterable
再以调试的方式调试下方代码:
class Test:
name = 'Lily'
age = 18
def __init__(self, gender, works, year):
self.gender = gender
self.works = works
self.year = year
def keys(self):
pass
t = Test('F', 'Student', 4)
dict(t)
上述代码对keys这个方法打上断点并以调试运行的方法将会发现程序将会执行到断点的地方。这是因为,在默认的情况下,我们在将对象直接传给dict的时候,dict将会去这个类里寻找keys这个方法,以期望拿到字典的所有键,而这些键是由我们自己定义的返回的,再看下面的例子:
class Test:
name = 'Lily'
age = 18
def __init__(self, gender, works, year):
self.gender = gender
self.works = works
self.year = year
def keys(self): # 必须是序列的格式,列表,元组都可
return ('name', 'age', 'works')
t = Test('F', 'Student', 4)
dict(t)
print(t['name'])
这里将会报:TypeError: ‘Test’ object is not subscriptable的错误,这是因为默认情况下我们无法使用中括号的方式访问一个对象,但是我们可以使用一个方法,以改变这种情况。我们再看下面的例子:
class Test:
name = 'Lily'
age = 18
def __init__(self, gender, works, year):
self.gender = gender
self.works = works
self.year = year
def keys(self):
return ('name', 'age', 'works') # 必须是序列的格式,列表,元组都可
def __getitem__(self, item):
return 1111
t = Test('F', 'Student', 4)
print(t['name'])
print(t['age'])
上面的代码段将会打印出:1111, 1111
__getitem__所返回的值就是我们中括号调用的结果,如果我们想拿到某个变量所对应的值,我们可以使用getattr获得,现在我们再看一下dict(对象)会打印出什么:
class Test:
name = 'Lily'
age = 18
def __init__(self, gender, works, year):
self.gender = gender
self.works = works
self.year = year
def keys(self):
return ('name', 'age', 'works')
def __getitem__(self, item):
return 1111
t = Test('F', 'Student', 4)
print(dict(t))
上述代码将会打印出:
{'name': 'Lily', 'age': 18, 'works': 'Student'}
以上代码我们可以看出来,我们已经将对象以字典的方法拿到类里的变量,无论是类变量还是实例变量。
实践才是真理,Fighting~