返回顶部
首页 > 资讯 > 后端开发 > Python >python中内置类型添加属性问题详解
  • 757
分享到

python中内置类型添加属性问题详解

2024-04-02 19:04:59 757人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录python中内置类型添加属性问题?普通对象绑定属性解决方法总结Python中内置类型添加属性问题? 最近项目 进行重构一些代码: 写代码过程中会遇到一个问题,我希望通过内置类型

Python中内置类型添加属性问题?

最近项目 进行重构一些代码:

写代码过程中会遇到一个问题,我希望通过内置类型生成的对象 添加属性,但是添加总是失败.

obj = object()
obj.name = 'frank'

报错如下:

Traceback (most recent call last):
File input, line 2, in
AttributeError: 'object' object has no attribute 'name'

普通对象绑定属性

我们知道python 语言的动态性, 是允许可以直接在是一个实例添加属性的。

class Animal:
    def eat(self):
        pass
    def sleep(self):
        pass

在python console 里面运行,可以看到是可以正常添加属性name

>>> animal = Animal()
>>> animal.name='dog'
>>> animal.name
'dog'

对比这两个类的不同点:

class Animal(object):

    def __init__(self):
        # print(sorted(dir(self)))
        res = set(dir(self)) - set(dir(object))
        print(res)
        print('########' * 10)
        res = set(dir(object)) - set(dir(self))
        print(res)
        pass

结果如下:

{'__module__', '__weakref__', '__dict__'}
################################################
set()

发现self 多了三个魔术方法。 我们来重点关注 __dict__ 方法,我们知道一个对象的属性,一般放在 这个属性上面的。 但是object 的实例 没有这个属性。

def main():
    obj = object()
    try:
        print(obj.__dict__)
    except AttributeError as e:
        print("ERROR:", e)

    animal = Animal()
    print(animal.__dict__, type(animal.__dict__))

    animal.name = 'animal'
    animal.age = 10
    print(animal.__dict__)

结果如下:

在 animal 对象中, 属性已经存放在了 __dict__ 中。 而obj对象就没有 __dict__ 这个属性。

而我有一个大胆的想法,有没有办法可以直接在obj 实例上把 __dict__ 绑定到这个实例obj 上面呢?

在python console 里面尝试下:

>>> obj = object()
>>> 
>>> obj.__dict__ = dict()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'object' object has no attribute '__dict__'
>>> setattr(obj,'__dict__',dict())
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'object' object has no attribute '__dict__'

发现并不能绑定成功,python 里面不允许这样绑定。

在python中 所有内置对象 list,dict,set ,object 等等,这些内置对象,不允许在里面添加 属性,方法等。

这样做是一个不好的行为,一旦你对内置对象做了修改,其他引用内置对象的代码,是否会受到影响呢 ? 这是一个不可预期的行为。

解决方法

比较好的做法:想绑定一个属性 在一个对象上面。可以自定义一个类。然后绑定属性,而不是在内置类型生成的对象进行绑定。

class Object(object):
    pass

>>> obj = Object()
>>> obj.__dict__
{}
>>> obj.name='frank'

>>> obj.__dict__
{'name': 'frank'}
>>> obj.name
'frank'

从网上找到一个解决方案在内置类型上面可以添加方法 ,但是记得不要在生产环境这样玩

import ctypes
class PyObject(ctypes.Structure):
    class PyType(ctypes.Structure):
       pass

    ssize = ctypes.c_int64 if ctypes.sizeof(ctypes.c_void_p) == 8 else ctypes.c_int32
    _fields_ = [
        ('ob_refcnt', ssize),
        ('ob_type', ctypes.POINTER(PyType)),
    ]

def sign(klass, func_name):
    def _(function):
        class SlotsProxy(PyObject):
            _fields_ = [('dict', ctypes.POINTER(PyObject))]

        name, target = klass.__name__, klass.__dict__
        proxy_dict = SlotsProxy.from_address(id(target))
        namespace = {}
        ctypes.pythonapi.PyDict_SetItem(
            ctypes.py_object(namespace),
            ctypes.py_object(name),
            proxy_dict.dict,
        )
        namespace[name][func_name] = function

    return _
# method-1
@sign(list, 'mean')
def mean(l): return sum(l) / len(l)
#
#
@sign(list, 'max')
def mean(l): 
  return max(l)

# method-2
sign(list, 'mean')(lambda l: sum(l) / len(l)

总结

不要在python内置对象上面添加方法和属性。因为这种行为是不可预期的,最好的做法继承内置对象,在派生子类中添加属性,方法等。

到此这篇关于python中内置类型添加属性问题详解的文章就介绍到这了,更多相关python添加属性内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: python中内置类型添加属性问题详解

本文链接: https://lsjlt.com/news/120573.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作