Ich möchte form.data['field']
und form.field.value
immer den gleichen Wert
Dies ist möglich, haben, weil sie ergänzten Namen und Indizierung beinhaltet - das heißt, komplett verschiedene Konstrukte von den Barnamesa
und b
, die Sie fragen, und für Ihre Anfrage ist absolut unmöglich. Warum fragen Sie nach etwas Unmöglichem und völlig anders als die (mögliche) Sache, die Sie eigentlich wollen?!
Vielleicht wissen Sie nicht, wie drastisch verschiedene Barnamen und dekorierte Namen sind. Wenn Sie auf einen Barnamen a
verweisen, erhalten Sie genau das Objekt a
, an das in diesem Bereich zuletzt gebunden wurde (oder eine Ausnahme, wenn es in diesem Bereich nicht gebunden war) - dies ist ein so tiefer und grundlegender Aspekt von Python Es kann unmöglich untergraben werden. Wenn Sie sich auf einen verzierten Namen x.y
beziehen, bitten Sie ein Objekt (das Objekt x
bezieht sich), bitte "das y
Attribut" zu liefern - und als Antwort auf diese Anforderung kann das Objekt völlig willkürliche Berechnungen durchführen (und Indexierung ist ziemlich ähnlich: Es erlaubt auch, dass beliebige Berechnungen als Antwort ausgeführt werden).
Nun ist Ihr "tatsächliches Desiderata" -Beispiel mysteriös, da in jedem Fall zwei Ebenen der Indexierung oder des Attribut-Erhaltens involviert sind, so dass die Subtilität, die Sie sich wünschen, auf viele Arten eingeführt werden könnte. Welche anderen Attribute soll form.field
haben, neben value
? Ohne daß weiteren .value
Berechnungen würden Möglichkeiten umfassen:
class Form(object):
...
def __getattr__(self, name):
return self.data[name]
und
class Form(object):
...
@property
def data(self):
return self.__dict__
Die Anwesenheit von .value
legt die erste Form Kommissionierung, sowie einen Art-of-nutzlosen wrapper:
class KouWrap(object):
def __init__(self, value):
self.value = value
class Form(object):
...
def __getattr__(self, name):
return KouWrap(self.data[name])
Wenn Zuweisungen wie form.field.value = 23
soll auch t gesetzt werden er Eintrag in form.data
, dann muss der Wrapper komplexer geworden in der Tat, und nicht alles, was nutzlos:
class MciWrap(object):
def __init__(self, data, k):
self._data = data
self._k = k
@property
def value(self):
return self._data[self._k]
@value.setter
def value(self, v)
self._data[self._k] = v
class Form(object):
...
def __getattr__(self, name):
return MciWrap(self.data, name)
Letzteres Beispiel etwa so nah wie es geht, in Python, das Gefühl der „Zeiger“, wie Sie scheinen zu wollen - aber es ist wichtig zu verstehen, dass solche Feinheiten können nur mit Indizierung und/oder dekoriert Namen, nie mit Barnamen arbeiten, wie Sie ursprünglich gefragt!
Vielleicht kann ich ähnlich eine Frage stellen zu S.Lott ist (aber produktiver): Sie können uns zeigen, ein echter Code, wo du das machen wolltest? Vielleicht sogar in einer anderen Sprache, die mehr nach Ihrem Geschmack ist? Es ist wahrscheinlich, dass das Problem, das Sie zu lösen versuchen, sich für eine pythonsche Lösung eignet, und das Fokussieren auf "Ich will Zeiger" verschleiert die wahre Antwort. –
Es braucht nicht viel Fantasie; Ich kann mir Dutzende Gründe vorstellen, dies zu tun. Es ist einfach nicht so, wie es in zeigerlosen Sprachen wie Python gemacht wird; Sie müssen es in einen Container einpacken, der nicht invariant ist, wie in Matts Antwort. –
@Ned: Aktualisiert Q. Ein anderes Beispiel wäre für eine Funktion, 'swap (a, b)'. Nicht, dass ich das jetzt brauche. – mpen