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

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

问题描述

我学习蟒蛇,虽然我觉得我得到了整个概念和Python的概念,今天我偶然发现了一块code的,我没有完全理解:

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:

说我有一个应该定义圈子,但缺乏一个体类:

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不引发未定义的名称错误。我也明白,通过的动态类型的我只是绑定变量的对象,每当我想要的,但应该不是一个属性半径在<$ C存在$ C>圆形类,让我做到这一点?

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 方法的新属性创建。而且它有时是有用的存储函数,如 __的init __ 这实际上没有该名称(例如装饰),这样的限制将打破。

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.

现在,这不是普遍适用。内建类型省略这个能力作为优化。通过 __ __插槽 ,还可以prevent这对用户定义的类。但是,这仅仅是一个空间优化(无需一个字典每个对象),而不是一个正确性事

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.

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

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