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 zu None.
  • Wenn Sie versuchen, legen Sie die Eigenschaft haben, warum nicht hinzufügen eine setter Methode?
InformationsquelleAutor dbmikus | 2013-07-26
Schreibe einen Kommentar