2013-07-26 42 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'方法 –

相關問題