为什么允许向已经实例化的对象添加属性? [英] Why is adding attributes to an already instantiated object allowed?

查看:144
本文介绍了为什么允许向已经实例化的对象添加属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究python,尽管我认为我了解了python的全部概念和概念,但今天我偶然发现了一段我不完全理解的代码:

I am studying python, and although I think I get the whole concept and notion of Python, today I stumbled upon a piece of code that I did not fully understand:

说我有一个应该定义Circles但缺少主体的类:

Say I have a class that is supposed to define Circles but lacks a body:

class Circle():
    pass

由于我尚未定义任何属性,因此该怎么做:

Since I have not defined any attributes, how can I do this:

my_circle = Circle()
my_circle.radius = 12

怪异的部分是Python接受上述声明.我不明白为什么Python不加undefined name error.我确实了解到,通过动态类型输入,我可以随时将变量绑定到对象,但是Circle类中不应该存在属性radius来允许我这样做吗?

The weird part is that Python accepts the above statement. I don't understand why Python doesn't raise an undefined name error. I do understand that via dynamic typing I just bind variables to objects whenever I want, but shouldn't an attribute radius exist in the Circle class to allow me to do this?

编辑:答案中包含许多精彩的信息! 感谢大家提供所有精彩的答案!很遗憾,我只能将其中一个标记为答案.

EDIT: Lots of wonderful information in your answers! Thank you everyone for all those fantastic answers! It's a pity I only get to mark one as an answer.

推荐答案

一个主要原则是,没有声明之类的东西.也就是说,您永远不会声明此类具有方法foo"或此类的实例具有属性栏",更不用说声明要存储在其中的对象类型了.您只需定义一个方法,属性,类等,然后将其添加.正如JBernardo指出的那样,任何__init__方法都具有相同的作用.随意将新属性的创建限制为名称为__init__的方法没有多大意义.有时将没有实际名称的函数(例如装饰器)存储为<​​c3>很有用,这样的限制会破坏这一点.

A leading principle is that there is no such thing as a declaration. That is, you never declare "this class has a method foo" or "instances of this class have an attribute bar", let alone making a statement about the types of objects to be stored there. You simply define a method, attribute, class, etc. and it's added. As JBernardo points out, any __init__ method does the very same thing. It wouldn't make a lot of sense to arbitrarily restrict creation of new attributes to methods with the name __init__. And it's sometimes useful to store a function as __init__ which don't actually have that name (e.g. decorators), and such a restriction would break that.

现在,这并非普遍如此.内置类型会忽略此功能以进行优化.通过 __slots__ ,您还可以在用户定义的类中防止这种情况.但这仅仅是空间优化(不需要每个对象都有字典),而不是正确性.

Now, this isn't universally true. Builtin types omit this capability as an optimization. Via __slots__, you can also prevent this on user-defined classes. But this is merely a space optimization (no need for a dictionary for every object), not a correctness thing.

如果您想要一个安全网,那就太糟糕了. Python没有提供一种语言,您不能合理地添加一种语言,最重要的是,使用该语言的Python程序员会避免使用它(阅读:几乎所有您想使用的语言).测试和纪律,对于确保正确性还有很长的路要走.如果可以避免,请不要使用自由来构成__init__ 之外的属性,并进行自动化测试.由于这样的欺骗,我很少出现AttributeError或逻辑错误,并且在发生的那些错误中,几乎所有错误都被测试捕获了.

If you want a safety net, well, too bad. Python does not offer one, and you cannot reasonably add one, and most importantly, it would be shunned by Python programmers who embrace the language (read: almost all of those you want to work with). Testing and discipline, still go a long way to ensuring correctness. Don't use the liberty to make up attributes outside of __init__ if it can be avoided, and do automated testing. I very rarely have an AttributeError or a logical error due to trickery like this, and of those that happen, almost all are caught by tests.

这篇关于为什么允许向已经实例化的对象添加属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆