在Python中,对象和字典之间有什么区别?

时间:2011-08-19 08:58:45

标签: python object-model

创建对象后,我可以随意添加和删除插槽,就像我可以使用字典一样。甚至方法也只是存储在插槽中的对象,所以我可能也可以在字典中添加方法。

我能用一个(非词典)对象做些什么我永远不会用字典做的吗? 或者是否可以设置一个完全看起来像某个类的对象的字典?

这个问题不是关于它们是如何创建的,而是关于我以后如何使用它们的问题。赞赏链接或参考。

5 个答案:

答案 0 :(得分:15)

  

创建对象后,我可以随意添加和删除插槽,就像我可以使用字典一样。甚至方法也只是存储在插槽中的对象,

小心说插槽 - __slots__ has a specific meaning in Python

  

所以我可能也可以在字典中添加方法。

foo = {}
foo.bar = 1

AttributeError: 'dict' object has no attribute 'bar'

不是默认情况下,你需要对它进行子类化 - 但是你正在使用一个类。相反,将函数放在字典中:

def bar():
    return 1

foo['bar'] = bar
foo['baz'] = lambda: 1
  

对于一个我永远无法用字典做的对象,我能做些什么吗?

这个问题实际上有一个错误的前提 - 词典是对象,所以你用词典做的任何事情都是用对象做的。对于这个答案的其余部分,当你说“对象”时,我会假装你的意思是“用户定义的类”。

不,您无法使用字典无法处理的用户定义类。甚至用字典实现了类。

class Foo(object):
    pass

print Foo.__dict__
# {'__dict__': <attribute '__dict__' of 'Foo' objects>, '__module__': '__main__', 
#      '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}

你可以用Python做的任何事情,你可以做到没有一个,有更多的工作(以及更难理解,使用和维护的代码)。甚至有人说Python类只是词典的语法糖。

最近有一个非常类似的问题被问到Do I need to learn about objects, or can I save time and just learn dictionaries?我认为我的答案也与此有关。

答案 1 :(得分:11)

当您调用对象的成员函数时,它们会将对象本身作为第一个参数传递。这样他们就可以修改他们所属对象的属性:

class Counter(object):
   def __init__(self):
      self.num = 0

   def inc(self):
      self.num += 1

count = Counter()
count.inc()

如果你只是在dict中存储了一堆函数,他们将得不到这样的支持。你必须手动传递dict才能达到同样的效果:

def Counter_inc(d):
   d['num'] += 1

def Counter_create():
   d = {
      'num': 0,
      'inc': Counter_inc,
   }
   return d

count = Counter_create()
count['inc'](count)

正如你可以看到的那样,它更加笨拙。虽然您可以使用原始dicts模拟对象的许多功能,但对对象提供特殊语言支持使它们更易于使用。

此外,还有一些功能直接使用对象类型信息,例如isinstance(),这些信息无法使用原始dicts轻松复制。

答案 2 :(得分:3)

其他答案有一些基础,但我想补充一点,你不能继承或实例化特定的词典。

class A(object): pass
class B(A): pass
a = A()

A = {}
B = ???
a = ???

因此,字典是对象,对象主要用字典实现(虽然我不知道具体细节),但它们是不同工作的不同工具。

答案 3 :(得分:1)

我想你问的是

o1={"some_method": lambda par1, par2: par1+par2}
o1["some_method"](1, 2)

VS

class SomeClass:
    def some_method(self, par1, par2):
        return par1+par2

o2=SomeClass()
o2.some_method(1, 2)

?如果是这样,我认为与实际观点的主要区别在于,o2.some_method将自己视为第一个参数而o1["some_method"]不是。

答案 4 :(得分:1)

对象是从类创建的{}:

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

student1 = Student('John', 31) # student1 is an object
print(student1) # does not print the expected result, we need to "convert" it to dictionary
print(student1.__dict__) # prints {'name': 'John', 'age': 31}

字典是{}不是从类创建的:

student2 = { 'name': 'Kevin', age: 15 } # student2 is a dictionary
print(student2) # prints {'name': 'Kevin', 'age': 15}