我是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}
为什么变量存在于一种意义上而不是另一种?是因为我没有明确地初始化它们或什么?
答案 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"
您将inty
和stringy
分配给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
的构造函数(记住:What
和Classy
是一样的)
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/