2013-07-26 15 views
3

当前我有一个通用函数,您可以在其中传递属性名称和类(它也适用于特定的对象实例,但我正在使用类),而功能将查找和调用在Python中通过字符串变量设置和获取@property方法

getattr(model_class, model_attribute) 

该属性上运行,它会通过调用(在一个对象实例这段时间)

settattr(model_obj,键,值)

修改的属性不过,我有一门课,我们有一个@property定义的方法而不是简单的属性,并且setattr不起作用。如何根据该属性方法的字符串名称动态获取@property

也许我可以使用__dict__,但看起来很脏并且不安全。

编辑:示例代码

广义函数

def process_general(mapping, map_keys, model_class, filter_fn, op_mode=op_modes.UPDATE): 
    """ 
    Creates or updates a general table object based on a config dictionary. 

    `mapping`: a configuration dictionary, specifying info about the table row value 
    `map_keys`: keys in the mapping that we use for the ORM object 
    `model_class`: the ORM model class we use the config data in 
    `op_mode`: the kind of operation we want to perform (delete, update, add, etc.) 

    Note that relationships between model objects must be defined and connected 
    outside of this function. 
    """ 
    # We construct a dictionary containing the values we need to set 
    arg_dict = make_keyword_args(map_keys, mapping) 

    # if we are updating, then we must first check if the item exists 
    # already 
    if (op_mode == op_modes.UPDATE): 
     # Find all rows that match by the unique token. 
     # It should only be one, but we will process all of them if it is the 
     # case that we didn't stick to the uniqueness requirement. 
     matches = filter_fn() 

     # Keep track of the length of the iterator so we know if we need to add 
     # a new row 
     num_results = 0 
     for match in matches: 
      # and we set all of the object attributes based on the dictionary 
      set_attrs_from_dict(match, arg_dict) 
      model_obj = match 
      num_results += 1 
     # We have found no matches, so just add a new row 
     if (num_results < 1): 
      model_obj = model_class(**arg_dict) 

     return model_obj 

    # TODO add support for other modes. This here defaults to add 
    else: 
     return model_class(**arg_dict) 

一个例子类中传递:

class Dataset(db.Model, UserContribMixin): 
    # A list of filters for the dataset. It can be built into the dataset filter form dict 
    # in get_filter_form. It's also useful for searching. 
    filters  = db.relationship('DatasetFilter', backref='dataset') 

    # private, and retrieved from the @property = select 
    _fact_select = db.relationship('DatasetFactSelect', order_by='DatasetFactSelect.order') 

    @property 
    def fact_select(self): 
     """ 
     FIXME: What is this used for? 

     Appears to be a list of strings used to select (something) from the 
     fact model in the star dataset interface. 

     :return: List of strings used to select from the fact model 
     :rtype: list 
     """ 

     # these should be in proper order from the relationship order_by clause 
     sels = [sel.fact_select for sel in self._fact_select] 
     return sels 
+0

可不可以给一类和你的函数调用的例子,并解释如何不给你想要什么? 'getattr'像'''语法一样透明地处理属性,所以我不确定你的问题是什么。 – delnan

+0

其实,在你经历任何的痛苦回答之前,让我在我的代码中多窥探一下。我认为问题是'getattr'不适用于属性,但是如果它能够工作,那么我确信这个错误在别的地方。我可以清理更多的东西,甚至可以找到解决方案。 – dbmikus

+0

hasattr,setattr和getattr在我的代码中工作。但我宣布它为'request = property(get_request,set_request,del_request)' – eri

回答

5

调用getattr(model_class, model_attribute)将返回属性对象model_attribute指。我假设你已经知道这一点,并试图访问属性对象的值。

class A(object): 

    def __init__(self): 
     self._myprop = "Hello" 

    @property 
    def myprop(self): 
     return self._myprop 

    @myprop.setter 
    def myprop(self, v): 
     self._myprop = v 

prop = getattr(A, "myprop") 

print prop 
# <property object at 0x7fe1b595a2b8> 

既然我们已经从类中获取了属性对象,我们想要访问它的值。属性有三种方法:fget,fsetfdel,它们提供对为该属性定义的getter,settterdeleter方法的访问。

既然myprop是一个实例方法,我们将不得不创建一个实例,以便我们可以调用它。

print prop.fget 
# <function myprop at 0x7fe1b595d5f0> 

print prop.fset 
# <function myprop at 0x7fe1b595d668> 

print prop.fdel # We never defined a deleter method 
# None 

a = A() 
print prop.fget(a) 
# Hello 
+0

'getattr(A(),'myprop')'立即返回属性的值。因此,'setattr'允许调用属性的'setter'方法 –

相关问题