dbm*_*kus 6 python attributes descriptor
目前我有一个通用函数,你可以传入一个属性名和一个类(它也适用于特定的对象实例,但我正在使用类),该函数将通过调用查找并操作该属性
getattr(model_class, model_attribute)
Run Code Online (Sandbox Code Playgroud)
它将通过调用(此时在对象实例上)来修改属性
settattr(model_obj,key,value)
但是,我有一个类,我们有一个@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)
Run Code Online (Sandbox Code Playgroud)
传入的示例类:
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
Run Code Online (Sandbox Code Playgroud)
调用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>
Run Code Online (Sandbox Code Playgroud)
现在我们已经从类中获取了属性对象,我们想要访问它的值.属性有三种方法fget,fset以及fdel提供访问getter,settter和deleter该属性定义的方法.
由于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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11811 次 |
| 最近记录: |