在python里如何动态添加类的动态属性呢?

body
{
font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI",Tahoma,Helvetica,Sans-Serif,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif;
font-size: 10.5pt;
line-height: 1.5;
}
html, body
{

}
h1 {
font-size:1.5em;
font-weight:bold;
}
h2 {
font-size:1.4em;
font-weight:bold;
}
h3 {
font-size:1.3em;
font-weight:bold;
}
h4 {
font-size:1.2em;
font-weight:bold;
}
h5 {
font-size:1.1em;
font-weight:bold;
}
h6 {
font-size:1.0em;
font-weight:bold;
}
img {
border:0;
max-width: 100%;
}
blockquote {
margin-top:0px;
margin-bottom:0px;
}
table {
border-collapse:collapse;
border:1px solid #bbbbbb;
}
td {
border-collapse:collapse;
border:1px solid #bbbbbb;
}

2010-10-19 08:49:20|  分类: 技术文章 |  标签:class  动态增加属性  python   |举报|字号 订阅

在python里如何动态添加类的动态属性呢?看下面的例子

class A(object):

a = 1

b = 2

def fun1(self):

print 'fun1'

def fun2(self):

print 'fun2'

a1 = A()

a1.c = 1

这里我们定义了一个类A,还有一个实例a1。a1.c = 1 只是增加实例的属性而不是增加类的属性。

我们知道python对象有一__dict__属性,那我们尝试这样操作:

setattr( A.__dict__, 'd', 1)

这样的操作会得到一下的错误:

TypeError: 'dictproxy' object has only read-only attributes (assign to .d)

这是什么意思呢?其实python对象里的获取“__dict__”属性,实际上获取的并不是实际的dict,获取的只是一个dictproxy。

在源码里typeobject.c里

static PyGetSetDef type_getsets[] = {

{"__name__", (getter)type_name, (setter)type_set_name, NULL},

{"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL},

{"__module__", (getter)type_module, (setter)type_set_module, NULL},

{"__dict__",  (getter)type_dict,  NULL, NULL},

{"__doc__", (getter)type_get_doc, NULL, NULL},

{0}

};

这里定义了__dict__对应的c的获取方法。

我们找到type_dict方法的实现

static PyObject *

type_dict(PyTypeObject *type, void *context)

{

if (type->tp_dict == NULL) {

Py_INCREF(Py_None);

return Py_None;

}

return PyDictProxy_New(type->tp_dict);

}

可以看到其实每次获取__dict__熟悉时,都是new一个dictproxy。

正确的操作应该是:

setattr( A, 'd', 1)

或者

setattr( a1.__class__, 'd', 1)

具体实现可以看classobject.c里的方法:

static int class_setattr(PyClassObject *op, PyObject *name, PyObject *v)

该函数会对非“__”开头的属性自动转到op->tp_dict。

来自为知笔记(Wiz)

时间: 2024-10-20 08:15:31

在python里如何动态添加类的动态属性呢?的相关文章

C# 动态添加类、动态添加类型、代码添加类型

原文:C# 动态添加类.动态添加类型.代码添加类型 引用控件: DLL下载地址:http://pan.baidu.com/s/1nv2GUWL public class TypeCreator { public static Type Creator(string ClassName, int PropertiesCount) { IDictionary<string, Type> Properties = new Dictionary<string, Type>(); Type

python 面向对象六 动态添加方法 __slots__限制动态添加方法

一.动态添加属性 1 >>> class Student(object): 2 pass 3 4 >>> st = Student() 5 >>> st.name = 'Jack' 6 >>> st.name 7 'Jack' 二.动态给实例添加方法 1 >>> from types import MethodType 2 >>> class Student(object): 3 pass 4 5

MUI 里js动态添加数字输入框后,增加、减少按钮无效

numbox 的自动初化是在 mui.ready 时完成的mui 页面默认会自动初始化页面中的所有数字输入框,动态构造的 DOM 需要进行手动初始化.比如:您动态创建了一个 ID 为 abc 的数字输入框,需要 mui('#abc').numbox() 初始化一下. 为什么 test() 放在 mui.plusReady 外边可以,而放在里边就不可以?这是因为 numbox 的自动初化是在 mui.ready 时完成的,直接在外部的 test() 执行发生在 mui.ready 之前,而写在 m

python协程之动态添加任务

https://blog.csdn.net/qq_29349715/article/details/79730786 python协程只能运行在事件循环中,但是一旦事件循环运行,又会阻塞当前任务.所以只能在当前进程中再开一个线程,这个线程的主要任务是运行事件循环,就是event_loop,因为他是一个无限循环,会阻塞当前线程.放一个自己写的demo,注释写的很详细.另外还有一点需要注意,一个事件循环中不能运行另外一个事件循环. import asyncio from threading impo

NGUI里Grid动态添加物体后,整理

1 //加入对象 2 foreach (Task t in tm.TaskDic.Values) 3 { 4 TaskItem ti= NGUITools.AddChild(grid.gameObject, TaskItemPerfab).GetComponent<TaskItem>(); 5 6 ti.SetTaskItem(t); 7 8 } 9 //grid自带的整理功能 10 grid.Reposition();

给python类动态添加方法(method)

群里有人问如何做到 def foo(): pass class Bar(object): pass Bar.set_instance_method(foo) b = Bar() b.foo() 这个其实还是比较简单的, 只要写个函数给类设置属性即可, 可根据需求是否用函数包装下, 或者用staticmethod这个decorator: import functools def foo(): print 'hello world' class Bar(object): def __init__(s

细说python类2——类动态添加方法和slots(转)

先说一下类添加属性方法和实例添加属性和方法的区别, 类添加属性属于加了一个以类为全局的属性(据说叫静态属性),那么以后类的每一个实例化,都具有这个属性.给类加一个方法也如此,以后类的每一个实例化都具备这个方法(但是据说叫动态方法.)但是给实例加一个属性,作用域就是这个实例,是与类没关系的(据说这种属性叫动态属性). Python类的实例可以动态的添加属性.举个例子,声明一个类A >>> class A(object):...   def __init__(self):...     pr

python类对象动态添加属性和方法

class Person(): #创建一个类 def __init__(self,name): #定义初始化信息. self.name = name li = Person('李') #实例化Person('李'),给变量li li.age = 20 #再程序没有停止下,将实例属性age传入.动态语言的特点. Person.age = None #这里使用类名来创建一个属性age给类,默认值是None.Python支持的动态属性添加. def eat(self): #定义一个方法,不过这个方法再

使用TypeDescriptor给类动态添加Attribute【转】

源文 : http://www.cnblogs.com/bicker/p/3326763.html 给类动态添加Attribute一直是我想要解决的问题,从msdn里找了很久,到Stack Overflow看了不少文章,算是最终有了答案. 先是有这样的一段解释 Attributes are static metadata. Assemblies, modules, types, members, parameters, and return values aren't first-class o