GVKun编程网logo

Python-如何动态地向类添加属性?(python 类 动态添加方法)

21

在这篇文章中,我们将为您详细介绍Python-如何动态地向类添加属性?的内容,并且讨论关于python类动态添加方法的相关问题。此外,我们还会涉及一些关于Groovy:向类中动态添加属性、php–动态

在这篇文章中,我们将为您详细介绍Python-如何动态地向类添加属性?的内容,并且讨论关于python 类 动态添加方法的相关问题。此外,我们还会涉及一些关于Groovy:向类中动态添加属性、php – 动态地向对象添加私有属性、php – 有没有办法禁止从类的实例向类中添加属性?、python - 装饰器+描述符(给类添加属性且属性类型审核)的知识,以帮助您更全面地了解这个主题。

本文目录一览:

Python-如何动态地向类添加属性?(python 类 动态添加方法)

Python-如何动态地向类添加属性?(python 类 动态添加方法)

目标是创建一个行为类似db结果集的模拟类。

因此,例如,如果数据库查询使用dict表达式返回{''ab'':100, ''cd'':200},那么我想看看:

>>> dummy.ab100

刚开始我以为我可以这样做:

ks = [''ab'', ''cd'']vs = [12, 34]class C(dict):    def __init__(self, ks, vs):        for i, k in enumerate(ks):            self[k] = vs[i]            setattr(self, k, property(lambda x: vs[i], self.fn_readyonly))    def fn_readonly(self, v)        raise "It is ready only"if __name__ == "__main__":    c = C(ks, vs)    print c.ab

c.ab返回一个属性对象。

用替换该setattrk = property(lambda x: vs[i])根本没有用。

那么在运行时创建实例属性的正确方法是什么?

答案1

小编典典

我想我应该扩大这个答案,因为我年纪大一些并且比较聪明,并且知道发生了什么事。迟到总比不到好。

你可以动态地向类添加属性。但这很重要:你必须将其添加到类中。

>>> class Foo(object):...     pass... >>> foo = Foo()>>> foo.a = 3>>> Foo.b = property(lambda self: self.a + 1)>>> foo.b4

property实际上,A 是称为描述符的事物的简单实现。它是一个对象,为给定类的给定属性提供自定义处理。Kinda就像一种从if树上拔出一棵大树的方法__getattribute__。

当我要求foo.b在上面的例子中,Python看到的是,b在类实现限定的描述符协议哪位只是意味着它是一个对象__get____set____delete__方法。描述符声明负责处理该属性,因此Python调用Foo.b.__get__(foo, Foo),并将返回值作为属性的值传回给你。在的情况下property,每一种方法只是调用fget,fset或fdel你传递给property构造函数。

描述符实际上是Python公开其整个OO实现的基本方法。实际上,还有一种比更为常见的描述符property。

>>> class Foo(object):...     def bar(self):...         pass... >>> Foo().bar<bound method Foo.bar of <__main__.Foo object at 0x7f2a439d5dd0>>>>> Foo().bar.__get__<method-wrapper ''__get__'' of instancemethod object at 0x7f2a43a8a5a0>

谦虚方法只是另一种描述符。它__get__以调用实例为第一个参数;实际上,它是这样做的:

def __get__(self, instance, owner):    return functools.partial(self.function, instance)

无论如何,我怀疑这就是为什么描述符仅在类上起作用的原因:它们是首先为类提供支持的东西的形式化形式。它们甚至是规则的例外:你显然可以为一个类分配描述符,而类本身就是type!的实例。实际上,尝试读取Foo.b静态呼叫property.__get__;当描述符作为类属性访问时,返回它们自己只是惯用的。

我认为几乎所有Python的OO系统都可以用Python表示非常酷。

Groovy:向类中动态添加属性

Groovy:向类中动态添加属性

Groovy:向类中动态添加属性

概述

使用Groovy中类的时候,虽然开始的时候会设定一些属性,但是运行的时候想在不修改源码的情况下,支持新的属性,可能就要借助与Groovy提供的动态编程的力量了。

调用类的属性的时候,如果属性不存在会调用类的

def propertyMissing(String name,value);

或者

def propertyMissing(String name);

如果是setter形式的调用属性那么是调用前者,getter是调用后者。如果是处理不存在的方式是:

def methodMissing(String name,args);

这里就不再赘述。

Adding properties to domain classes on the fly using groovy propertyMissing feature这篇文章对于属性的动态添加处理有了相对详细的叙述,但是给出的代码在调试的时候,没有通过,因此写了自己的版本。

实现

首先实现一个支持属性动态添加的基类

class DynamicEntity { def dynamicProperties = [:] //setter def propertyMissing(String name,value) { dynamicProperties.put(name,value) } //getter def propertyMissing(String name) { dynamicProperties.get(name) } }

然后让自己定义的类继承这个基类即可。

class VisualTreeNode extends DynamicEntity{
    def String element
    def VisualTreeNode left
    def VisualTreeNode right
}

最后,在使用的时候就可以放心地使用了。当然这种情况下,可能会出现属性积压的情况,后面会添加处理属性的方法,包括去除不必要的属性,限定支持的属性名。

说明:如果对于不存在的属性先调用getter方法,那么返回的值就是null。

php – 动态地向对象添加私有属性

php – 动态地向对象添加私有属性

我有一节课:

class Foo {
    // Accept an assoc array and appends its indexes to the object as property
    public function extend($values){
        foreach($values as $var=>$value){
            if(!isset($this->$var))
                $this->$var = $value;
        }
    }
}

$Foo = new Foo;
$Foo->extend(array('name' => 'Bee'));

现在,$Foo对象具有值为Bee的公共名称属性.

如何更改扩展函数以使变量变为私有?

编辑
使用私有阵列是另一种方式,绝对不是我的答案.

解决方法:

简单,糟糕的设计.

在运行时添加私有[!]字段的目的是什么?现有的方法不能依赖于这些添加的字段,而且你会搞乱对象的功能.

如果你希望你的对象表现得像一个hashmap [即你可以拨打$obj – > newField = $newValue],考虑使用magic __get和__set方法.

php – 有没有办法禁止从类的实例向类中添加属性?

php – 有没有办法禁止从类的实例向类中添加属性?

有没有办法禁止从类的实例中将properties添加到类中.

我的意思是:

考虑这个课程:

class a {
 private $v1;
 public $v2;

 function func(){
 ...
 }
}

如果我这样做:

$ins = new a;
$ins->temp = "A variable created from outside the class! C*ap!";
var_dump($ins);

输出:

object(a)#1 (3) {
  ["v1":"a":private]=>
  NULL
  ["v2"]=>
  NULL
  ["temp"]=>
  string(48) "A variable created from outside the class! C*ap!"
}

这会被禁用吗?`

解决方法:

也许你可以实现__set()并从那里抛出异常:

class a {
    private $v1;
    public $v2;

    public function __set($name, $value) {
        throw new Exception("Cannot add new property \$$name to instance of " . __CLASS__);
    }
}

python - 装饰器+描述符(给类添加属性且属性类型审核)

python - 装饰器+描述符(给类添加属性且属性类型审核)

装饰器+描述符

实现给一个类添加属性且对添加的时,对属性进行类型审核:

def zsq(**kwargs):
    def fun(obj):
        for i,j in kwargs.items():
            setattr(obj,i,mxf(i,j))
        return obj
    return fun

class mxf():
    def __init__(self,na,ty):
        self.na = na
        self.ty = ty
    def __get__(self, instance, owner):
        return instance.ty
    def __set__(self, instance, value):
        if isinstance(value,self.ty):
            instance.__dict__[self.na] = value
        else:
            print("%s=%s 录入类型错误...."%(self.na,value))

@zsq(name=str,old=int)
class Student():
    def __init__(self,name,old):
        self.name = name
        self.old = old

A1 = Student(''anec'',18)
A2 = Student(4343,''123'')
print(A1.__dict__)
print(A2.__dict__)

 

关于Python-如何动态地向类添加属性?python 类 动态添加方法的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Groovy:向类中动态添加属性、php – 动态地向对象添加私有属性、php – 有没有办法禁止从类的实例向类中添加属性?、python - 装饰器+描述符(给类添加属性且属性类型审核)的相关知识,请在本站寻找。

本文标签: