当前位置: 首页 > 面试题库 >

Python-无法设置对象类的属性

长孙瑞
2023-03-14
问题内容

因此,我在回答这个问题的同时一直在使用Python,但发现这是无效的:

o = object()
o.attr = 'hello'

由于AttributeError: 'object' object has no attribute 'attr'。但是,对于从对象继承的任何类,它都是有效的:

class Sub(object):
    pass

s = Sub()
s.attr = 'hello'

打印s.attr将按预期显示“ hello”。为什么会这样呢?在Python语言规范中,有哪些规定不能将属性分配给香草对象?


问题答案:

为了支持任意属性分配,对象需要一个__dict__:与对象关联的字典,可以在其中存储任意属性。否则,就无处放置新属性。

的实例object并没有随身携带__dict__-如果它这样做了,可怕的循环依赖问题(之前因为dict,像其他所有的事情,从继承object;-),这将鞍每一个在Python对象有一个字典,这将意味着开销当前没有或不需要字典的每个对象中有多少字节(基本上,所有不具有任意可分配属性的对象都没有或不需要字典)。

例如,使用出色的pympler项目(你可以从此处通过svn获得它),我们可以进行一些测量…:

>>> from pympler import asizeof
>>> asizeof.asizeof({})
144
>>> asizeof.asizeof(23)
16

你不希望每个人都int占用144个字节而不是16个字节,对吧?

现在,当你上课(继承任何内容)时,情况发生了变化:

>>> class dint(int): pass
... 
>>> asizeof.asizeof(dint(23))
184

…的__dict__ 是现在又增加了(加,多一点开销) -所以一个dint实例可以有任意的属性,但是你付出相当的灵活性的空间成本。

那么,如果int只需要一个额外的属性foobar,该怎么办…?这是一种罕见的需求,但是Python确实为此目的提供了一种特殊的机制…

>>> class fint(int):
...   __slots__ = 'foobar',
...   def __init__(self, x): self.foobar=x+100
... 
>>> asizeof.asizeof(fint(23))
80

......没有相当的微小的作为int,你得注意!(甚至是两个int,一个self,一个self.foobar-可以重新分配第二个),但肯定比a好得多dint

当类具有__slots__特殊属性(字符串序列),那么class语句(更准确地说,默认元类type)并没有装备该类的每个实例有一个__dict__(有任意属性,因此的能力),只是一个有限,是具有给定名称的一组刚性“槽”(基本上是每个可以容纳对某个对象的引用的位置)。

换来的是失去灵活性,你获得了很多每个实例的字节(如果只有有闲逛周围情况不计其数可能有意义的,但是,有是用例为)。



 类似资料:
  • 本文向大家介绍Python面向对象基础入门之设置对象属性,包括了Python面向对象基础入门之设置对象属性的使用技巧和注意事项,需要的朋友参考一下 前言 前面我们已经介绍了 python面向对象入门教程之从代码复用开始(一) ,这篇文章主要介绍的是关于Python面向对象之设置对象属性的相关内容,下面话不多说了,来一起看看详细的介绍吧 用类存储数据 类实际上就是一个数据结构,对于python而言,

  • 问题内容: 我遇到的烧瓶SQLAlchemy的一个问题,我可以设置对象的属性 place_collections ,但是当我想设置为对象属性 的地方 ,发生了错误: 如何设置联接搜索对象的属性,有人可以帮助我吗? 它们都是 “ flask_sqlalchemy.BaseQuery” 类。 模型 问题答案: 将返回您的对象集合。这类似于普通的香草SQLAlchemy。 但是,从SQLAlchemy

  • 您好,我有一个小问题要理解打字稿以及如何创建具有属性的对象。 我不明白我怎么能创建一个对象,并在创建后添加一些值。 我读了许多博客,有可能的解决方案,但没有任何工作。我得到的只是“无法设置未定义的属性‘书名’”。 我已经试过这个解决方案了。类型脚本和字段初始值设定项 如何在TypeScript中基于接口文件定义创建对象? 在打字稿中如何修复无法设置未定义的属性“第一” 至少我知道,我还没有完全理解

  • 问题内容: 有没有一种方法可以设置javascript对象的默认属性,例如: IE可以忽略,Chrome Frame减轻了我的头痛。 问题答案: 自从几年前我问这个问题以来,事情进展顺利。 代理是ES6的一部分。以下示例可在Chrome,Firefox,Safari和Edge中运行:

  • 问题内容: 我有一个对象,它可以是任何数量的深度,并且可以具有任何现有属性。例如: 在此我想设置(或覆盖)属性,如下所示: 属性字符串可以具有任何深度,并且值可以是任何类型/事物。 如果属性键已经存在,则不需要合并对象和数组作为值。 前面的示例将产生以下对象: 如何实现这种功能? 问题答案: 此函数使用您指定的参数应添加/更新容器中的数据。请注意,您需要跟踪架构中的哪些元素是容器,哪些是值(字符串

  • 我有一个对象,可以是任何数量的层次深,可以有任何现有的属性。例如: 在此基础上,我希望设置(或覆盖)如下属性: 属性字符串可以有任何深度,值可以是任何类型/事物。 如果属性键已经存在,则不需要合并作为值的对象和数组。 上一个示例将生成以下对象: 如何实现这样的功能?