Set-und Get - @property-Methode in Python durch die string-variable
Derzeit habe ich eine verallgemeinerte Funktion, wo Sie können gehen in ein Attribut name und eine Klasse (es würde auch funktionieren mit bestimmten Objekt-Instanzen, aber ich bin mit Klassen), die Funktion zu suchen und zu betreiben, die auf diesem Attribut durch den Aufruf
getattr(model_class, model_attribute)
und es wird das Attribut ändern, indem Sie aufrufen (auf ein Objekt-Instanz dieser Zeit)
settattr(model_obj, key, value)
Allerdings habe ich eine Klasse, wo wir eine @property
Methode definiert, anstatt ein einfaches Attribut, und setattr
funktioniert nicht. Wie kann ich dynamisch Holen Sie sich die @property
basierend auf einem string-Namen für diese property-Methode?
Vielleicht könnte ich mit __dict__
aber das scheint schmutzig und nicht so sicher.
Edit: Beispiel-code
Die verallgemeinerte Funktion
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)
Einer Beispiel-Klasse übergeben:
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
- Können Sie uns ein Beispiel für eine Klasse und einen Anruf an Ihre Funktion, und erklären Sie, wie diese nicht geben, was Sie wollen?
getattr
Griffe Eigenschaften wie transparent, wie die.
syntax, also ich bin mir nicht sicher, was dein problem ist. - Eigentlich, bevor Sie gehen durch alle Schmerzen, diese zu beantworten, lassen Sie mich schnüffeln in meinem code mehr. Ich dachte, das Problem war, dass
getattr
funktionierte nicht für Eigenschaften, aber wenn es funktionieren sollte, dann bin ich sicher, dass der Fehler liegt woanders. Ich kann deutlich mehr Zeug und vielleicht sogar die Lösung finden. - hasattr,setattr und getattr funktioniert in meinem code. aber ich erklärte es als
request = property(get_request, set_request, del_request)
- Also schrieb ich einen Teil der Frage falsch.
setattr
funktioniert nicht für die Eigenschaft. In diesem speziellen Fall, wir versuchen, die Eigenschaft zuNone
. - Wenn Sie versuchen, legen Sie die Eigenschaft haben, warum nicht hinzufügen eine
setter
Methode?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Aufrufen
getattr(model_class, model_attribute)
wird die Eigenschaft zurück-Objekt, dasmodel_attribute
verweist. Ich nehme an, Sie wissen das bereits und versuchen, Zugriff auf den Wert der Eigenschaft Objekt.Nun, dass wir erhalten haben, die Eigenschaft Objekt aus der Klasse, die wir wollen, um Zugriff auf dessen Wert. Eigenschaften haben drei Methoden
fget
,fset
, undfdel
, die den Zugriff auf diegetter
,settter
, unddeleter
Methoden definiert, die für diese Eigenschaft.Seit
myprop
ist eine Instanz-Methode, wir haben eine Instanz zu schaffen, so können wir es nennen.getattr(A(), 'myprop')
gibt Sie den Wert der Eigenschaft sofort. Alsosetattr
ermöglicht das aufrufensetter
- Methode der Eigenschaftgetattr(A, "myprop")
sehenAttributeError
. Ich habe einen anderen/wahrscheinlich besser beantworten.Für die meisten Allgemeinen Fall, diesem Beispiel zu Folgen: