Python2-打印对象';s的默认属性

Python2-打印对象';s的默认属性,python,class,Python,Class,我是OOP新手,但我正在尝试查看对象的变量。其他Stack-O答案建议使用对象。或变量(对象)。因此,我进入Python shell尝试一个快速示例,但我注意到这两个答案都不会打印对象的默认属性,只打印新分配的属性,例如: >>> class Classy(): ... inty = 3 ... stringy = "whatevs" ... >>> object = Classy() >>> object.inty 3 &

我是OOP新手,但我正在尝试查看对象的变量。其他Stack-O答案建议使用
对象。
变量(对象)
。因此,我进入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}

为什么变量在某种意义上存在,而在另一种意义上不存在?是因为我没有显式地初始化它们还是什么?

您可以使用
vars
\uuuuu dict\uuuu
作为类名,而不是实例:

备选案文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__']}

\uu dict\uu
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'}
dict of foo_function={}
Horrible thing? http://www.nooooooooooooooo.com/

干杯

重要的一点是,在Python中,一切都是对象(包括函数和
声明本身)

执行此操作时:

class Classy():
    inty = 3
    stringy = "whatevs"
您将
inty
stringy
分配给
类,而不是实例。选中此项:

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

print(Classy.__dict__)
等等。。。带有
指令的
?是的,因为
Classy
也是一个实例(类型为
classobj
,因为您正在使用,顺便说一句,您不应该真正这样做……您应该从
对象继承,这样您可以访问更多的好东西)

哪个输出

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

5
whatevs
为什么??因为当您尝试在实例上获取
inty
时,Python将首先在实例的
\uuuuu dict\uuuuu
中查找它。如果找不到它,它将转到该类的
\uu dict\uu
。这就是发生在
classy.stringy
上的事情。它是否在
classy
实例中?没有。它在
Classy
类中吗?是的!哎呀,把那个还给我。。。你看到的就是这个

另外,我提到Classy类是一个对象,对吗?因此,您可以将其分配给以下内容:

What = Classy  # No parenthesis
foo = What()
print(foo.inty)
您将看到在
Classy中“附加”的
5
。\uuuu init\uuu
因为当您执行
What=Classy
时,您将
class Classy
分配给名为
What
的变量,当您执行
foo=What()
时,您实际上正在运行
Classy
的构造函数(记住:
What
Classy
是一回事)

Python允许的另一件事(我个人不喜欢,因为这样会使代码很难理解)是“动态”地将属性附加到实例:

将输出

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)
产出:

{'inty': 3, 'stringy': 'whatevs'}
{'inty': 3, 'stringy': 'whatevs'}
dict of foo_function={}
Horrible thing? http://www.nooooooooooooooo.com/

这些变量分配给类,而不是对象,因此请尝试
Classy.\uuu dict\uuu
(包含更多的内部属性)但是当我输入object.inty时,它返回
3
。这不意味着变量也被分配给了对象吗?@mblakesley不,这不是什么意思。此外,这些不是真正的“默认值”,它们是类属性。@mblakesley查看关于属性访问在Python中如何工作的解释。再次注意,这里没有实例属性,但有类属性。@juanpa.arrivillaga回到这里,我想我现在明白了。所以我最初的困惑是因为
object.attr
将引用存在的对象属性ts,否则它将引用class属性。这可能很方便,但乍看起来很混乱。好吧,这就是我的想法,但我的原始场景对我来说仍然没有意义。当
对象时,
如何才能返回值。而
对象。uuu dict\uuu
没有?当然!我希望你玩这些东西玩得开心。a等你学会元类再说!!:这真的很有趣!
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/