今天在编写一些特别糟糕的代码时,我偶然发现了这种神秘的行为.下面的Python 3程序打印随机选择的属性object.这是怎么发生的?
对于非确定性的一个明显的怀疑是vars(object)字典的随机排序,但我看不出它是如何导致观察到的行为.我得到的一个假设是,它是由__setattr__被覆盖的顺序引起的,但是lambda总是只被调用一次(通过打印调试检查)这一事实证明了这一点.
class TypeUnion:
pass
class t:
pass
def super_serious(obj):
proxy = t()
for name, val in vars(object).items():
if not callable(val) or type(val) is type:
continue
try:
setattr(t, name, lambda _, *x, **y: val)
except AttributeError:
pass
return proxy
print(super_serious(TypeUnion()).x)
Run Code Online (Sandbox Code Playgroud)
注意:上述程序并未试图做任何有用的事情; 它比原来大大减少了.
我正在尝试找到一种将文件结构表示为 python 对象的方法,这样我就可以轻松获得特定路径,而不必键入所有字符串。这适用于我的情况,因为我有一个静态文件结构(不变)。
我想我可以将目录表示为类,将目录中的文件表示为类/静态变量。
我希望能够浏览 python 对象,以便它返回我想要的路径,即:
print(FileStructure.details.file1) # root\details\file1.txt
print(FileStructure.details) # root\details
Run Code Online (Sandbox Code Playgroud)
我从下面的代码中得到的是:
print("{0}".format(FileStructure())) # root
print("{0}".format(FileStructure)) # <class '__main__.FileStructure'>
print("{0}".format(FileStructure.details)) # <class '__main__.FileStructure.details'>
print("{0}".format(FileStructure.details.file1)) # details\file1.txt
Run Code Online (Sandbox Code Playgroud)
到目前为止我拥有的代码是......
import os
class FileStructure(object): # Root directory
root = "root"
class details(object): # details directory
root = "details"
file1 = os.path.join(root, "file1.txt") # File in details directory
file2 = os.path.join(root, "file2.txt") # File in details directory
def __str__(self):
return f"{self.root}"
def __str__(self):
return f"{self.root}"
Run Code Online (Sandbox Code Playgroud)
我不想必须实例化该类才能完成这项工作。我的问题是:
我遇到了__getattr__内置的,并想知道何时使用它.我很难从文档
http://docs.python.org/reference/datamodel.html#中考虑实际使用.什么是如何在代码中使用和有用的实际例子?
我正在编写一个解析文件的库,创建一个表示文件的对象,并允许将对象导出回文件.
我想验证每次更改这些值时都包含所需的标题和列.因此,我试图使用@property装饰器设置验证.
我在@property的python文档中注意到,如果属性名称为'variable',则使用'_variable'.据我所知,前面的单个下划线表示该变量仅供弱内部使用.但是,我认为@property装饰器的意思是任何设置变量的调用都会导致setter函数运行.
_headers = None
required_headers = ['FIELD_DELIM', 'VIDEO_FORMAT', 'FPS']
@property
def headers(self):
return self._headers
@headers.setter
def headers(self, value):
for header in self.required_headers:
if header not in value:
raise Exception
self._headers = value
Run Code Online (Sandbox Code Playgroud)
虽然这段代码有效,但我知道我仍然可以通过执行myObject._headers = value来绕过我的setter.
有没有办法可以确保始终执行验证而不依赖于用户尊重_headers是供内部使用?
我读了一下python的对象属性查找(这里:https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/#object-attribute-lookup).
看起来很直接,所以我试了一下(python3):
class A:
def __getattr__(self, attr):
return (1,2,3)
a = A()
a.foobar #returns (1,2,3) as expected
a.__getattribute__('foobar') # raises AttributeError
Run Code Online (Sandbox Code Playgroud)
我的问题是不是两个应该是相同的?
为什么第二个会引发属性错误?
所以答案显然是a.foobarIS的逻辑不同于逻辑a.__getattribute("foobar").根据数据模型:a.foobar调用a.__getattribute("foobar"),如果它引发AttributeError,则调用a.-__getattr__('foobar')
所以看来这篇文章在他们的图表中有一个错误.它是否正确?
还有一个问题:a.foobar的真正逻辑在哪里?我认为它在__getattribute__但显然不完全.
编辑: 不重复
__getattr__与__getattribute__之间的区别.我问这里有什么之间的不同object.foo和object.__getattribute__("foo").这__getattr__与vs 不同,__getatribute__这是微不足道的......