__用于约束Python中属性创建的setattr\uuuuuuuuuuu与uuuuuuuu插槽
我一直在读关于如何降低Python类的动态性,特别是通过不允许用户动态创建新属性。我读过了,还有。实际上,有人认为,__用于约束Python中属性创建的setattr\uuuuuuuuuuu与uuuuuuuu插槽,python,attributes,slots,setattr,Python,Attributes,Slots,Setattr,我一直在读关于如何降低Python类的动态性,特别是通过不允许用户动态创建新属性。我读过了,还有。实际上,有人认为,\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu可以打破酸洗。(有人能证实这一点吗?) 然而,我刚刚阅读了Python2.2的whatsnew,实际上建议使用\uuuuu slots\uuuu来限制属性创建,而不仅仅是像其他人建议的那样进行优化。就Python的历史而言,有人知道\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu的初
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
可以打破酸洗。(有人能证实这一点吗?)
然而,我刚刚阅读了Python2.2的whatsnew,实际上建议使用\uuuuu slots\uuuu
来限制属性创建,而不仅仅是像其他人建议的那样进行优化。就Python的历史而言,有人知道\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
的初衷是什么吗?约束变量的创建是一个被滥用的特性还是一个错误?人们是如何看待实践中使用的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
?有很多人看到过重载来限制属性创建吗?哪一个最好?如果你更熟悉一种或另一种方法,请随时发布你所知道的方法的优缺点。另外,如果你有不同的解决问题的方法,请分享!(请不要重复已在中表示的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
编辑:我希望避免讨论“为什么?”,但第一个答案表明这将出现,所以我将在这里陈述。在所讨论的项目中,我们使用这些类来存储“配置信息”,允许用户使用其(用户)参数设置对象的属性,然后将对象传递给程序的另一部分。这些对象不仅仅是存储参数,所以字典不起作用。我们已经有用户意外地键入了错误的属性名称,并最终创建了一个新属性,而不是设置程序期望的属性之一。这不会被检测到,因此用户认为他们正在设置参数,但看不到预期结果。这让用户感到困惑,而且很难发现。通过约束属性创建,异常将被抛出,而不是静默地传递
编辑2,重新酸洗:这些对象将是我们将来想要存储的东西,酸洗似乎是一种很好的方法。如果\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
编辑3:我还应该提到,内存保护不是一个问题。这些对象很少会被创建,因此任何节省的内存都可以忽略不计(比如3-12GB机器上的10s千字节)。为什么要限制开发人员这样做?除了“我不想让他们这么做”之外,还有什么技术原因吗?如果没有,就不要这样做
无论如何,使用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但是,如果某些代码需要对象具有\uuu dict\uuu
,则无法使用它
如果有很好的理由限制它(同样,你确定有吗?)或者你需要节省那一点点内存,请选择\uuuuu插槽\uuuu
阅读说明后,您可能希望使用\uuuuu setattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。这样,您可以显示一些更有用的信息,例如哪些类似属性可用。可能的实现如下所示:
class Test(object):
__slots__ = ('foo', 'bar', 'moo', 'meow', 'foobar')
def __setattr__(self, name, value):
try:
object.__setattr__(self, name, value)
except AttributeError:
alts = sorted(self.__slots__, key=lambda x: levenshtein(name, x))
msg = "object has no attribute '{}', did you mean '{}'?"
raise AttributeError(msg.format(name, alts[0]))
我使用的levenshtein()
是来自的实现4。对于不太聪明的用户,您可能希望使错误更加详细,并包括所有接近的匹配项,而不仅仅是第一个匹配项
您可以通过创建一个仅包含\uuuu setattr\uuu
方法的mixin类来进一步改进代码。这样,您就可以将代码排除在实际类之外,并且在必要时还可以使用自定义的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
(只需使用超级(…)。\uu?除了“我不想让他们这么做”之外,还有什么技术原因吗?如果没有,就不要这样做
无论如何,使用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但是,如果某些代码需要对象具有\uuu dict\uuu
,则无法使用它
如果有很好的理由限制它(同样,你确定有吗?)或者你需要节省那一点点内存,请选择\uuuuu插槽\uuuu
阅读说明后,您可能希望使用\uuuuu setattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。这样,您可以显示一些更有用的信息,例如哪些类似属性可用。可能的实现如下所示:
class Test(object):
__slots__ = ('foo', 'bar', 'moo', 'meow', 'foobar')
def __setattr__(self, name, value):
try:
object.__setattr__(self, name, value)
except AttributeError:
alts = sorted(self.__slots__, key=lambda x: levenshtein(name, x))
msg = "object has no attribute '{}', did you mean '{}'?"
raise AttributeError(msg.format(name, alts[0]))
我使用的levenshtein()
是来自的实现4。对于不太聪明的用户,您可能希望使错误更加详细,并包括所有接近的匹配项,而不仅仅是第一个匹配项
您可以通过创建一个仅包含\uuuu setattr\uuu
方法的mixin类来进一步改进代码。这样,您就可以将代码排除在实际类之外,并且在必要时还可以自定义\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
(只需在mixin中使用超级(…)。\uuuuuuuuuuuuuuuuu我对您的用例的建议是使用\uuuuSetAttr\uuuuuuuuuuuuuu
并在使用Python模块无法识别属性名称时发出警告。我对您的用例的建议是使用\uuuuuuSetAttr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
并在使用Python模块无法识别属性名称时发出警告。我相信插槽是正确的int