Python2 - 打印对象的默认属性

时间:2017-12-30 02:30:45

标签: python class

我是OOP的新手,但我正试着看一个对象的变量。其他Stack-O答案建议使用object.__dict__vars(object)。所以我进入Python shell尝试一个简单的例子,但是我注意到这些答案都没有打印出对象的默认属性,只有新分配的属性,例如:

>>> class Classy():
...     inty = 3
...     stringy = "whatevs"
... 
>>> object = Classy()
>>> object.inty
3
>>> object.__dict__
{}
>>> vars(object)
{}
>>> object.inty = 27
>>> vars(object)
{'inty': 27}
>>> object.__dict__
{'inty': 27}

为什么变量存在于一种意义上而不是另一种?是因为我没有明确地初始化它们或什么?

3 个答案:

答案 0 :(得分:1)

您可以将vars__dict__与类名一起使用,而不是实例:

选项1:

class Classy:
   inty = 3
   stringy = "whatevs"

final_vals = {a:b for a, b in vars(Classy).items() if a not in ['__doc__', '__module__']}

输出:

{'inty': 3, 'stringy': 'whatevs'}

选项2:

final_vals = {a:b for a, b in Classy.__dict__.items() if a not in ['__doc__', '__module__']}

答案 1 :(得分:1)

.__dict__vars方法无法正常工作的原因是因为您没有使用python的self引用为您的类定义构造函数。以下内容将满足您的需求:

class Classy():
    def __init__(self):
        self.inty = 3
        self.stringy = 'whatevs'

object = Classy()
object.__dict__
vars(object)

输出:

{'inty': 3, 'stringy': 'whatevs'}
{'inty': 3, 'stringy': 'whatevs'}

干杯!

答案 2 :(得分:1)

重要的是要理解在Python中,一切都是对象(包括函数,以及class声明本身)

执行此操作时:

class Classy():
    inty = 3
    stringy = "whatevs"

您将intystringy分配给Class,而不是实例。检查一下:

class Classy():
    inty = 3
    stringy = "whatevs"

print(Classy.__dict__)

等待...... class __dict__?是的,因为Classy也是一个类型为classobj的实例,因为您正在使用old style classes,这是您不应该做的,顺便说一下......您应该继承object,这样可以访问更多好东西

>>> print(type(Classy))
<type 'classobj'>

现在,如果您创建了一个优雅的实例,并为其添加了inty值,那么您将拥有:

class Classy():
    inty = 3
    stringy = "whatevs"

    def __init__(self):
        self.inty = 5

classy = Classy()
print("__dict__ of instance: %s" % classy.__dict__)
print("__dict__ of Class: %s" % classy.__class__.__dict__)

哪个输出

__dict__ of instance: {'inty': 5}
__dict__ of Class: {'__module__': '__main__', 'inty': 3, '__doc__': None, '__init__': <function __init__ at 0x1080de410>, 'stringy': 'whatevs'}

在实例的inty中看到__dict__是5,但在班级的__dict__中仍然是3?这是因为现在您有两个inty:一个附加到classy,一个是Classy的实例,另一个附加到类Classy本身(其中反过来又是classobj

的一个实例

如果你做了

classy = Classy()
print(classy.inty)
print(classy.stringy)

您会看到:

5
whatevs

为什么呢?因为当您尝试在实例上获取inty时,Python将首先在实例__dict__中查找它。如果它找不到它,它将转到该类的__dict__。这就是classy.stringy上发生的事情。它在classy 实例中吗? Nopes。是在Classy 吗?是的! Aight,归还那个......那就是你看到的那个。

另外,我提到Classy类是一个对象,对吧?因此,您可以将其分配给其他类似的东西:

What = Classy  # No parenthesis
foo = What()
print(foo.inty)

并且您会看到附加的5&#34;在Classy.__init__中,因为当您执行What = Classy时,您将class Classy分配给名为What的变量,当您执行foo=What()时,您{39} ;实际运行Classy的构造函数(记住:WhatClassy是一样的)

Python允许的另一件事(我个人不喜欢,因为它使代码很难遵循)是将属性附加到实例&#34;在飞行中&#34;:

classy = Classy()
try:
    print(classy.other_thing)
except AttributeError:
    print("Oh, dang!! No 'other_thing' attribute!!")
classy.other_thing = "hello"
print(classy.other_thing)

将输出

Oh, dang!! No 'other_thing' attribute!!
hello

哦,我说过功能是对象吗?是的,它们是......因此,你也可以为它们分配属性(也是使代码真正令人困惑的东西),但你可以做到......

def foo_function():
    return None # Very dummy thing we're doing here
print("dict of foo_function=%s" % foo_function.__dict__)
foo_function.horrible_thing_to_do = "http://www.nooooooooooooooo.com/"
print("Horrible thing? %s" % foo_function.horrible_thing_to_do)

输出:

dict of foo_function={}
Horrible thing? http://www.nooooooooooooooo.com/