webentwicklung-frage-antwort-db.com.de

Zugriff auf Diktierschlüssel wie ein Attribut?

Ich finde es bequemer, als obj.foo auf ictcode statt auf obj['foo'] zuzugreifen, also habe ich diesen Ausschnitt geschrieben:

class AttributeDict(dict):
    def __getattr__(self, attr):
        return self[attr]
    def __setattr__(self, attr, value):
        self[attr] = value

Ich gehe jedoch davon aus, dass es einen Grund geben muss, dass Python diese Funktionalität nicht standardmäßig bereitstellt. Was wären die Vorbehalte und Fallstricke beim Zugriff auf Diktierschlüssel auf diese Weise?

231

Der beste Weg dies zu tun ist:

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self

Einige Profis:

  • Es funktioniert tatsächlich!
  • Keine Klassenmethoden für Wörterbücher werden gespiegelt (z. B. funktionieren .keys() einwandfrei).
  • Attribute und Elemente sind immer synchron
  • Wenn Sie versuchen, auf einen nicht vorhandenen Schlüssel als Attribut zuzugreifen, wird AttributeError anstelle von KeyError ausgelöst.

Nachteile:

  • Methoden wie .keys() funktionieren not gut, wenn sie durch eingehende Daten überschrieben werden
  • Verursacht ein Speicherleck in Python <2.7.4/Python3 <3.2.3
  • Pylint geht mit E1123(unexpected-keyword-arg) und E1103(maybe-no-member) Bananen
  • Für den Uneingeweihten scheint es reine Magie zu sein.

Eine kurze Erklärung, wie das funktioniert

  • Alle Python-Objekte speichern intern ihre Attribute in einem Wörterbuch mit dem Namen __dict__.
  • Es ist nicht erforderlich, dass das interne Wörterbuch __dict__ "nur ein einfaches Diktat" sein muss, sodass wir dem internen Wörterbuch jede Unterklasse von dict() zuordnen können.
  • In unserem Fall weisen wir einfach die Instanz AttrDict() zu, die wir instanziieren (wie in __init__).
  • Durch den Aufruf der super()-Methode __init__() haben wir sichergestellt, dass sie sich (bereits) genau wie ein Wörterbuch verhält, da diese Funktion den gesamten Dictionary Instantiation-Code aufruft.

Ein Grund, warum Python diese Funktionalität nicht standardmäßig bereitstellt

Wie in der "cons" -Liste erwähnt, kombiniert dies den Namespace gespeicherter Schlüssel (die von beliebigen und/oder nicht vertrauenswürdigen Daten stammen können) mit dem Namespace eingebauter dict-Methodenattribute. Zum Beispiel:

d = AttrDict()
d.update({'items':["jacket", "necktie", "trousers"]})
for k, v in d.items():    # TypeError: 'list' object is not callable
    print "Never reached!"
245
Kimvais

Sie können alle zulässigen Zeichenfolgezeichen als Teil des Schlüssels verwenden, wenn Sie die Array-Notation ..__ verwenden. Beispiel: obj['!#$%^&*()_']

118
Hery

Von Diese andere SO - Frage Es gibt ein großartiges Implementierungsbeispiel, das Ihren vorhandenen Code vereinfacht. Wie wäre es mit:

class AttributeDict(dict): 
    __getattr__ = dict.__getitem__
    __setattr__ = dict.__setitem__

Viel prägnanter und lässt keinen Raum für zusätzliche Möglichkeiten, in Zukunft in Ihre __getattr__- und __setattr__-Funktionen zu gelangen. 

67
slacy

Wobei ich die gestellte Frage beantworte

Warum bietet Python nicht sofort an?

Ich vermute, dass es mit dem Zen of Python zu tun hat: "Es sollte einen - und am besten nur einen - offensichtlichen Weg geben, dies zu tun." Dies würde zwei offensichtliche Möglichkeiten schaffen, auf Werte aus Wörterbüchern zuzugreifen: obj['key'] Und obj.key.

Vorsichtsmaßnahmen und Fallstricke

Dazu gehören mögliche Unklarheiten und Unklarheiten im Code. Das folgende kann für jemanden verwirrend sein , der Ihren Code zu einem späteren Zeitpunkt pflegen wird, oder sogar für Sie, wenn Sie es sind Ich werde für eine Weile nicht darauf zurückkommen. Wieder aus Zen : "Lesbarkeit zählt!"

>>> KEY = 'spam'
>>> d[KEY] = 1
>>> # Several lines of miscellaneous code here...
... assert d.spam == 1

Wenn d instanziiert ist oder KEY ist definiert oder d[KEY] Wird weit entfernt von dem Ort zugewiesen, an dem d.spam Verwendet wird. Dies kann leicht zu Verwirrung darüber führen, was getan wird, da dies keine allgemein gebräuchliche Redewendung ist. Ich weiß, es könnte mich verwirren.

Wenn Sie zusätzlich den Wert von KEY wie folgt ändern (aber die Änderung von d.spam Verpassen), erhalten Sie jetzt:

>>> KEY = 'foo'
>>> d[KEY] = 1
>>> # Several lines of miscellaneous code here...
... assert d.spam == 1
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
AttributeError: 'C' object has no attribute 'spam'

IMO, die Mühe nicht wert.

Andere Dinge

Wie andere angemerkt haben, können Sie jedes Hash-Objekt (nicht nur eine Zeichenfolge) als Diktierschlüssel verwenden. Zum Beispiel,

>>> d = {(2, 3): True,}
>>> assert d[(2, 3)] is True
>>> 

ist legal, aber

>>> C = type('C', (object,), {(2, 3): True})
>>> d = C()
>>> assert d.(2, 3) is True
  File "<stdin>", line 1
  d.(2, 3)
    ^
SyntaxError: invalid syntax
>>> getattr(d, (2, 3))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: getattr(): attribute name must be string
>>> 

ist nicht. Auf diese Weise erhalten Sie Zugriff auf den gesamten Bereich druckbarer Zeichen oder anderer Hash-Objekte für Ihre Wörterbuchschlüssel, die Sie beim Zugriff auf ein Objektattribut nicht haben. Dies ermöglicht solche Magie wie eine zwischengespeicherte Objekt-Metaklasse, wie das Rezept aus dem Python Cookbook (Ch. 9) .

Wobei ich redaktionell arbeite

Ich bevorzuge die Ästhetik von spam.eggs Gegenüber spam['eggs'] (Ich denke, es sieht sauberer aus) und habe wirklich Lust auf diese Funktionalität bekommen, als ich namedtuple . Aber die Bequemlichkeit, das Folgende tun zu können, übertrifft es.

>>> KEYS = 'spam eggs ham'
>>> VALS = [1, 2, 3]
>>> d = {k: v for k, v in Zip(KEYS.split(' '), VALS)}
>>> assert d == {'spam': 1, 'eggs': 2, 'ham': 3}
>>>

Dies ist ein einfaches Beispiel, aber ich verwende Dikte häufig in anderen Situationen als in der Notation obj.key (D. H. Wenn ich Prefs in einer XML-Datei einlesen muss). In anderen Fällen, in denen ich versucht bin, eine dynamische Klasse zu instanziieren und aus ästhetischen Gründen einige Attribute darauf zu legen, verwende ich weiterhin ein Diktat zur Konsistenz, um die Lesbarkeit zu verbessern.

Ich bin mir sicher, dass das OP dies schon lange zu seiner Zufriedenheit gelöst hat, aber wenn er diese Funktionalität immer noch haben möchte, dann schlage ich vor, dass er eines der Pakete von pypi herunterlädt, die es bereitstellen:

  • Haufen ist derjenige, den ich besser kenne. Unterklasse von dict, damit Sie alle diese Funktionen haben.
  • AttrDict sieht auch so aus, als wäre es auch ziemlich gut, aber ich kenne es nicht so gut und habe es nicht gesehen durch die Quelle so detailliert wie ich habe Haufen .
  • Wie in den Kommentaren von Rotareti erwähnt, ist Bunch veraltet, aber es gibt eine aktive Abzweigung mit dem Namen Munch.

Um jedoch die Lesbarkeit seines Codes zu verbessern, empfehle ich nachdrücklich, dass er seine Notationsstile nicht mischt . Wenn er diese Schreibweise bevorzugt, sollte er einfach ein dynamisches Objekt instanziieren, seine gewünschten Attribute hinzufügen und es einen Tag nennen:

>>> C = type('C', (object,), {})
>>> d = C()
>>> d.spam = 1
>>> d.eggs = 2
>>> d.ham = 3
>>> assert d.__dict__ == {'spam': 1, 'eggs': 2, 'ham': 3}

Wobei ich aktualisiere, um eine Folgefrage in den Kommentaren zu beantworten

In den Kommentaren (unten) fragt Elmo :

Was ist, wenn Sie tiefer gehen wollen? (Bezogen auf Typ (...))

Obwohl ich diesen Anwendungsfall noch nie verwendet habe (ich neige dazu, aus Konsistenzgründen geschachteltes dict zu verwenden), funktioniert der folgende Code:

>>> C = type('C', (object,), {})
>>> d = C()
>>> for x in 'spam eggs ham'.split():
...     setattr(d, x, C())
...     i = 1
...     for y in 'one two three'.split():
...         setattr(getattr(d, x), y, i)
...         i += 1
...
>>> assert d.spam.__dict__ == {'one': 1, 'two': 2, 'three': 3}
66
Doug R.

Vorsichtsmaßnahme: Aus einigen Gründen scheinen Klassen wie diese das Multiprocessing-Paket zu durchbrechen. Ich hatte gerade eine Weile mit diesem Fehler zu kämpfen, bevor ich diese SO fand: Suche nach Ausnahme in Python Multiprocessing

19
Ryan

Was wäre, wenn Sie einen Schlüssel wünschen, der eine Methode ist, beispielsweise __eq__ oder __getattr__?

Und Sie könnten keinen Eintrag haben, der nicht mit einem Buchstaben begann. Daher ist es nicht möglich, 0343853 als Schlüssel zu verwenden.

Und was ist, wenn Sie keine Zeichenfolge verwenden möchten?

18

Sie können eine praktische Containerklasse aus der Standardbibliothek abrufen:

from argparse import Namespace

um zu vermeiden, dass Code-Bits kopiert werden müssen. Kein Standardwörterbuchzugriff, aber einfach wieder zu bekommen, wenn Sie es wirklich wollen. Der Code in argparse ist einfach,

class Namespace(_AttributeHolder):
    """Simple object for storing attributes.

    Implements equality by attribute names and values, and provides a simple
    string representation.
    """

    def __init__(self, **kwargs):
        for name in kwargs:
            setattr(self, name, kwargs[name])

    __hash__ = None

    def __eq__(self, other):
        return vars(self) == vars(other)

    def __ne__(self, other):
        return not (self == other)

    def __contains__(self, key):
        return key in self.__dict__
15
lindyblackburn

tupel können Diktasten verwendet werden. Wie würden Sie in Ihrem Konstrukt auf Tuple zugreifen?

namedtuple ist eine praktische Struktur, die Werte über den Attributzugriff bereitstellen kann.

11
Senthil Kumaran

Im Allgemeinen funktioniert es nicht. Nicht alle gültigen Diktierschlüssel machen adressierbare Attribute ("den Schlüssel"). Sie müssen also vorsichtig sein.

Python-Objekte sind im Wesentlichen alle Wörterbücher. Ich bezweifle also, dass es viel Leistung oder andere Strafen gibt.

8
tallseth

Hier ist ein kurzes Beispiel für unveränderliche Datensätze, die integrierte collections.namedtuple verwenden:

def record(name, d):
    return namedtuple(name, d.keys())(**d)

und ein Anwendungsbeispiel:

rec = record('Model', {
    'train_op': train_op,
    'loss': loss,
})

print rec.loss(..)
4
Ben Usman

Dies bezieht sich nicht auf die ursprüngliche Frage, sollte aber für Leute nützlich sein, die wie ich hier enden, wenn sie nach einer Bibliothek suchen, die diese Funktionalität bietet.

Addict es ist eine großartige lib für dieses: https://github.com/mewwts/addict es kümmert sich um viele Anliegen, die in früheren Antworten erwähnt wurden.

Ein Beispiel aus den Dokumenten:

body = {
    'query': {
        'filtered': {
            'query': {
                'match': {'description': 'addictive'}
            },
            'filter': {
                'term': {'created_by': 'Mats'}
            }
        }
    }
}

Mit Süchtigen:

from addict import Dict
body = Dict()
body.query.filtered.query.match.description = 'addictive'
body.query.filtered.filter.term.created_by = 'Mats'
4
gonz

Wie wäre es mit Prodict , der kleinen Python-Klasse, die ich schrieb um sie alle zu beherrschen :)

Außerdem erhalten Sie Auto-Code-Vervollständigung, rekursive Objekt-Instantiierungen und Auto-Typkonvertierung!

Sie können genau das tun, wonach Sie gefragt haben:

p = Prodict()
p.foo = 1
p.bar = "baz"

Beispiel 1: Typhinweise

class Country(Prodict):
    name: str
    population: int

turkey = Country()
turkey.name = 'Turkey'
turkey.population = 79814871

auto code complete

Beispiel 2: Automatische Typumwandlung

germany = Country(name='Germany', population='82175700', flag_colors=['black', 'red', 'yellow'])

print(germany.population)  # 82175700
print(type(germany.population))  # <class 'int'>

print(germany.flag_colors)  # ['black', 'red', 'yellow']
print(type(germany.flag_colors))  # <class 'list'>
3
Ramazan Polat

Anscheinend gibt es jetzt eine Bibliothek für diese - https://pypi.python.org/pypi/attrdict - die diese exakte Funktionalität plus rekursives Mischen und Json-Laden implementiert. Vielleicht einen Blick wert.

3
Yurik

Ich habe dies basierend auf den Eingaben aus diesem Thread erstellt. Ich muss allerdings Odict verwenden, also musste ich get und attr setzen. Ich denke, dass dies für die meisten Sonderanwendungen funktionieren sollte.

Die Nutzung sieht so aus:

# Create an ordered dict normally...
>>> od = OrderedAttrDict()
>>> od["a"] = 1
>>> od["b"] = 2
>>> od
OrderedAttrDict([('a', 1), ('b', 2)])

# Get and set data using attribute access...
>>> od.a
1
>>> od.b = 20
>>> od
OrderedAttrDict([('a', 1), ('b', 20)])

# Setting a NEW attribute only creates it on the instance, not the dict...
>>> od.c = 8
>>> od
OrderedAttrDict([('a', 1), ('b', 20)])
>>> od.c
8

Die Klasse:

class OrderedAttrDict(odict.OrderedDict):
    """
    Constructs an odict.OrderedDict with attribute access to data.

    Setting a NEW attribute only creates it on the instance, not the dict.
    Setting an attribute that is a key in the data will set the dict data but 
    will not create a new instance attribute
    """
    def __getattr__(self, attr):
        """
        Try to get the data. If attr is not a key, fall-back and get the attr
        """
        if self.has_key(attr):
            return super(OrderedAttrDict, self).__getitem__(attr)
        else:
            return super(OrderedAttrDict, self).__getattr__(attr)


    def __setattr__(self, attr, value):
        """
        Try to set the data. If attr is not a key, fall-back and set the attr
        """
        if self.has_key(attr):
            super(OrderedAttrDict, self).__setitem__(attr, value)
        else:
            super(OrderedAttrDict, self).__setattr__(attr, value)

Dies ist ein ziemlich cooles Muster, das bereits im Thread erwähnt wurde. Wenn Sie jedoch nur ein Diktat in ein Objekt konvertieren möchten, das mit Auto-Completion in einer IDE usw. funktioniert, gehen Sie wie folgt vor:

class ObjectFromDict(object):
    def __init__(self, d):
        self.__dict__ = d
3
Rafe

Sie müssen keine eigenen as setattr () schreiben und getattr () existiert bereits.

Der Vorteil von Klassenobjekten kommt wahrscheinlich bei der Klassendefinition und Vererbung zum Tragen.

3
David W

Um der Antwort etwas Abwechslung zu verleihen, hat sci-kit learn dies als Bunch implementiert:

class Bunch(dict):                                                              
    """ Scikit Learn's container object                                         

    Dictionary-like object that exposes its keys as attributes.                 
    >>> b = Bunch(a=1, b=2)                                                     
    >>> b['b']                                                                  
    2                                                                           
    >>> b.b                                                                     
    2                                                                           
    >>> b.c = 6                                                                 
    >>> b['c']                                                                  
    6                                                                           
    """                                                                         

    def __init__(self, **kwargs):                                               
        super(Bunch, self).__init__(kwargs)                                     

    def __setattr__(self, key, value):                                          
        self[key] = value                                                       

    def __dir__(self):                                                          
        return self.keys()                                                      

    def __getattr__(self, key):                                                 
        try:                                                                    
            return self[key]                                                    
        except KeyError:                                                        
            raise AttributeError(key)                                           

    def __setstate__(self, state):                                              
        pass                       

Sie benötigen lediglich die setattr- und getattr-Methoden. Die getattr sucht nach Diktiertasten und die Suche nach tatsächlichen Attributen. Die setstaet ist ein Fix für das Beizen/Entpacken von "Bündeln" - bei eingehenden Prüfungen https://github.com/scikit-learn/scikit-learn/issues/6196

3
user2804865

Lassen Sie mich eine weitere Implementierung posten, die auf der Antwort von Kinvais aufbaut, aber Ideen aus dem in http://databio.org/posts/python_AttributeDict.html vorgeschlagenen AttributeDict integriert.

Der Vorteil dieser Version ist, dass sie auch für verschachtelte Wörterbücher funktioniert:

class AttrDict(dict):
    """
    A class to convert a nested Dictionary into an object with key-values
    that are accessible using attribute notation (AttrDict.attribute) instead of
    key notation (Dict["key"]). This class recursively sets Dicts to objects,
    allowing you to recurse down nested dicts (like: AttrDict.attr.attr)
    """

    # Inspired by:
    # http://stackoverflow.com/a/14620633/1551810
    # http://databio.org/posts/python_AttributeDict.html

    def __init__(self, iterable, **kwargs):
        super(AttrDict, self).__init__(iterable, **kwargs)
        for key, value in iterable.items():
            if isinstance(value, dict):
                self.__dict__[key] = AttrDict(value)
            else:
                self.__dict__[key] = value
2
kadee
class AttrDict(dict):

     def __init__(self):
           self.__dict__ = self

if __== '____main__':

     d = AttrDict()
     d['ray'] = 'hope'
     d.Sun = 'shine'  >>> Now we can use this . notation
     print d['ray']
     print d.Sun
1
h_vm

Sie können dict_to_obj https://pypi.org/project/dict-to-obj/ verwenden. Es macht genau das, wonach Sie gefragt haben

From dict_to_obj import DictToObj
a = {
'foo': True
}
b = DictToObj(a)
b.foo
True

1
Alon Barad

Lösung ist:

DICT_RESERVED_KEYS = vars(dict).keys()


class SmartDict(dict):
    """
    A Dict which is accessible via attribute dot notation
    """
    def __init__(self, *args, **kwargs):
        """
        :param args: multiple dicts ({}, {}, ..)
        :param kwargs: arbitrary keys='value'

        If ``keyerror=False`` is passed then not found attributes will
        always return None.
        """
        super(SmartDict, self).__init__()
        self['__keyerror'] = kwargs.pop('keyerror', True)
        [self.update(arg) for arg in args if isinstance(arg, dict)]
        self.update(kwargs)

    def __getattr__(self, attr):
        if attr not in DICT_RESERVED_KEYS:
            if self['__keyerror']:
                return self[attr]
            else:
                return self.get(attr)
        return getattr(self, attr)

    def __setattr__(self, key, value):
        if key in DICT_RESERVED_KEYS:
            raise AttributeError("You cannot set a reserved name as attribute")
        self.__setitem__(key, value)

    def __copy__(self):
        return self.__class__(self)

    def copy(self):
        return self.__copy__()

Wie von Doug erwähnt, gibt es ein Bunch-Paket, mit dem Sie die obj.key-Funktionalität erreichen können. Eigentlich gibt es eine neuere Version

NeoBunch

Es hat jedoch eine großartige Funktion, die Ihr Diktat durch die Funktion neobunchify in ein NeoBunch-Objekt konvertiert. Ich verwende häufig Mako-Vorlagen, und die Weitergabe von Daten als NeoBunch-Objekte macht sie viel lesbarer. Wenn Sie also ein normales Diktum in Ihrem Python-Programm verwenden, die Punktnotation jedoch in einer Mako-Vorlage angezeigt werden soll, können Sie es so verwenden:

from mako.template import Template
from neobunch import neobunchify

mako_template = Template(filename='mako.tmpl', strict_undefined=True)
data = {'tmpl_data': [{'key1': 'value1', 'key2': 'value2'}]}
with open('out.txt', 'w') as out_file:
    out_file.write(mako_template.render(**neobunchify(data)))

Und die Mako-Vorlage könnte so aussehen:

% for d in tmpl_data:
Column1     Column2
${d.key1}   ${d.key2}
% endfor
1
mizu

Sie können es mit dieser Klasse tun, die ich gerade gemacht habe. Mit dieser Klasse können Sie das Map-Objekt wie ein anderes Wörterbuch (einschließlich Json-Serialisierung) oder mit der Punktnotation verwenden. Ich hoffe dir helfen:

class Map(dict):
    """
    Example:
    m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
    """
    def __init__(self, *args, **kwargs):
        super(Map, self).__init__(*args, **kwargs)
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.iteritems():
                    self[k] = v

        if kwargs:
            for k, v in kwargs.iteritems():
                self[k] = v

    def __getattr__(self, attr):
        return self.get(attr)

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(Map, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(Map, self).__delitem__(key)
        del self.__dict__[key]

Verwendungsbeispiele:

m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
# Add new key
m.new_key = 'Hello world!'
print m.new_key
print m['new_key']
# Update values
m.new_key = 'Yay!'
# Or
m['new_key'] = 'Yay!'
# Delete key
del m.new_key
# Or
del m['new_key']
1
epool

Das ist was ich benutze

args = {
        'batch_size': 32,
        'workers': 4,
        'train_dir': 'train',
        'val_dir': 'val',
        'lr': 1e-3,
        'momentum': 0.9,
        'weight_decay': 1e-4
    }
args = namedtuple('Args', ' '.join(list(args.keys())))(**args)

print (args.lr)
0
mujjiga

Dies ist keine 'gute' Antwort, aber ich dachte, das wäre geschickt (es behandelt keine verschachtelten Diktate in der aktuellen Form). Wickeln Sie Ihr Diktier einfach in eine Funktion ein:

def make_funcdict(d={}, **kwargs)
    def funcdict(d={}, **kwargs):
        funcdict.__dict__.update(d)
        funcdict.__dict__.update(kwargs)
        return funcdict.__dict__
    funcdict(d, **kwargs)
    return funcdict

Jetzt haben Sie eine etwas andere Syntax. Um auf die Diktierelemente als Attribute zuzugreifen, f.key. Um auf die Dict-Elemente (und andere Dict-Methoden) auf die übliche Weise zuzugreifen, machen Sie f()['key'] und wir können das Dict bequem aktualisieren, indem Sie f mit Schlüsselwortargumenten und/oder einem Wörterbuch aufrufen

Beispiel

d = {'name':'Henry', 'age':31}
d = make_funcdict(d)
>>> for key in d():
...     print key
... 
age
name
>>> print d.name
... Henry
>>> print d.age
... 31
>>> d({'Height':'5-11'}, Job='Carpenter')
... {'age': 31, 'name': 'Henry', 'Job': 'Carpenter', 'Height': '5-11'}

Und da ist es. Ich freue mich, wenn jemand Vor- und Nachteile dieser Methode vorschlägt.

0
DylanYoung

Was wären die Vorbehalte und Fallstricke beim Zugriff auf Diktierschlüssel auf diese Weise?

Wie @Henry nahe legt, besteht der Grund, warum Dotted-Access in Diktaten nicht verwendet werden darf, darin, dass Diktennamen auf Python-gültige Variablen beschränkt werden, wodurch alle möglichen Namen eingeschränkt werden. 

Im Folgenden finden Sie Beispiele dafür, warum Punktzugriff im Allgemeinen bei einem Diktat d nicht hilfreich ist:

Gültigkeit

Die folgenden Attribute sind in Python ungültig: 

d.1_foo                           # enumerated names
d./bar                            # path names
d.21.7, d.12:30                   # decimals, time
d.""                              # empty strings
d.john doe, d.denny's             # spaces, misc punctuation 
d.3 * x                           # expressions  

Stil

PEP8-Konventionen würden der Attributbenennung eine weiche Einschränkung auferlegen:

A. Reservierte Schlüsselwort (oder eingebaute Funktion) Namen: 

d.in
d.False, d.True
d.max, d.min
d.sum
d.id

Wenn der Name eines Funktionsarguments mit einem reservierten Schlüsselwort kollidiert, ist es im Allgemeinen besser, einen einzelnen nachfolgenden Unterstrich anzuhängen.

B. Die Fallregel zu Methoden und Variablennamen :

Variablennamen folgen der gleichen Konvention wie Funktionsnamen.

d.Firstname
d.Country

Verwenden Sie die Funktionsbenennungsregeln: Kleinbuchstaben mit durch Unterstriche getrennten Wörtern, um die Lesbarkeit zu verbessern.


Manchmal werden diese Bedenken in Bibliotheken wie Pandas aufgeworfen, wodurch der punktförmige Zugriff auf DataFrame-Spalten nach Namen ermöglicht wird. Der Standardmechanismus zum Auflösen von Benennungseinschränkungen ist auch Array-Notation - eine Zeichenfolge in Klammern. 

Wenn diese Einschränkungen nicht auf Ihren Anwendungsfall zutreffen, gibt es mehrere Optionen für gepunktete Datenstrukturen .

0
pylang