Seite 1 von 1

Frage zu Python-Code

Verfasst: Freitag 28. September 2012, 10:11
von Steffo
Hallo,
ich habe eine Frage zu einem Python-Code.

Als erstes wird die Variable "cfg" wie ein Objekt verwendet:

Code: Alles auswählen

print "Size of Descriptor", cfg.bLength
print "Configuration Descriptor", cfg.bDescriptorType
Anschließend kommt der Teil, der mich verwirrt, da die Variable "cfg" nun anschließend wie ein Array und innerhalb des Arrays ein Tupel(?) erstellt(?) wird:

Code: Alles auswählen

interface_number = cfg[(0,0)].bInterfaceNumber
Hab sowas in noch keiner Programmiersprache gesehen, deswegen bin ich gerade ratlos. :K

So viel kann ich sagen: Es wird auf einen Pointer zugegriffen, trotzdem verstehe ich die Logik nicht. :)

Code: Alles auswählen

struct usb_config_descriptor
{
    unsigned char  bLength;
    unsigned char  bDescriptorType;
    unsigned short wTotalLength;
    unsigned char  bNumInterfaces;
    unsigned char  bConfigurationValue;
    unsigned char  iConfiguration;
    unsigned char  bmAttributes;
    unsigned char  MaxPower;

    struct usb_interface *interface;

    unsigned char *extra;	/* Extra descriptors */
    int extralen;
};
Kann mir jemand sagen, was dahinter steckt?

Danke im Voraus!

L. G.
Steffo

Re: Frage zu Python-Code

Verfasst: Freitag 28. September 2012, 12:19
von Steffo
Ich habe übrigens in der Python-Lib die Einbindung gefunden:

Code: Alles auswählen

class Configuration(object):
    r"""Configuration descriptor object."""
    def __init__(self, cfg):
        self.iConfiguration = cfg.iConfiguration
        self.maxPower = cfg.bMaxPower << 2
        self.remoteWakeup = (cfg.bmAttributes >> 5) & 1
        self.selfPowered = (cfg.bmAttributes >> 6) & 1
        self.totalLength = cfg.wTotalLength
        self.value = cfg.bConfigurationValue
        self.interfaces = [
                            list(g) for k, g in _interop._groupby(
                                    _interop._sorted(
                                        [Interface(i) for i in cfg],
                                        key=lambda i: i.interfaceNumber
                                    ),
                                    lambda i: i.alternateSetting)
                        ]
Scheinbar wird dieses Gewurschtel irgendwie mit Lambda umgesetzt. :shock:

Re: Frage zu Python-Code

Verfasst: Freitag 28. September 2012, 13:34
von sparrow
Du weißt, dass du eine Klasse indexierbar machen kannst? Damit kannst du sie dann wie ein dict oder eine Liste verwenden.

http://docs.python.org/reference/datamo ... ence-types

Oder in Code:

Code: Alles auswählen

>>> class Test(object):
	def __getitem__(self, key):
		print "Oh, jemand will etwas, das kitzelt!"
	def normal(self):
		print "Ich bin eine ganz normale funktion"

		
>>> t = Test()
>>> t.normal()
Ich bin eine ganz normale funktion
>>> t[0]
Oh, jemand will etwas, das kitzelt!

Re: Frage zu Python-Code

Verfasst: Freitag 28. September 2012, 13:43
von BlackJack
@Steffo: Die Variable `cfg` wird *immer* wie ein Objekt verwendet, denn alles was man an einen Namen binden kann ist in Python ein Objekt.

Du meinst dass das Objekt sowohl Attribute hat, als auch den Indexoperator unterstützt. Aber auch das ist nicht wirklich ungewöhnlich.

Der Indexoperator bedeutet auch nicht, dass sich das Objekt wie ein ”Array” verhalten muss. Auf Abbildungen wie `dict`-Objekte wird ja auch mit diesem Operator zugegriffen. Was dann auch bedeutet, dass das Argument jedes beliebige Objekt sein darf, inklusive Tupel. Das wird ja nicht ”innerhalb des Arrays […] erstellt”, sondern als Schlüssel verwendet. Das ist bei ganz normalen `dict`-Exemplaren ein übliches Vorgehen wenn man einen Schlüssel haben möchte, der sich aus mehreren Komponenten zusammensetzen soll.

Letztlich steht hinter dem Zugriff über den Indexoperator auch nur eine Methode. Wenn Du das noch in keiner Programmiersprache gesehen hast, dann hast Du anscheinend noch keine Programmiersprache mit Operatorüberladung gesehen. Was jetzt aber auch nicht soo ungewöhnlich ist. In C++ gibt es das zum Beispiel auch.

Was ``obj[key]`` bedeutet und was man als `key` übergeben kann hängt von der Implementierung des Datentyps von `obj` ab. Die entsprechenden Methoden zur Unterstützung des Indexoperators implementiert man üblicherweise wenn der Typ für einen ”Container” steht, der Objekte enthält. Entweder als Sequenz, dann sind die Argumente ganze Zahlen von 0 bis zur Länge des Containers, oder als Abbildung, dann sind die Argumente irgendwie geartete Schlüssel die auf enthaltene Elemente abgebildet werden können.

Hier handelt es sich um USB-Schnittstellen und ich vermute mal der Schlüssel ist ein Tupel aus Bus- und Gerätenummer, weil man die eindeutig auf eine Schnittstelle abbilden kann. Was der Indexoperator bedeutet muss man halt in der Dokumentation zum entsprechenden Datentyp nachlesen, auf den man ihn anwenden möchte.

Die ``lambda``-Funktionen dürften nicht unmittelbar mit dem Indexzugriff zu tun haben. Das sind Argumente für `_interop._groupby` und `_interop._sorted` und dürften nur für die Ausführung dieser beiden Funktionen verwendet werden.

Der lesende Indexzugriff wird über die `__getitem__()`-Methode abgewickelt.

Re: Frage zu Python-Code

Verfasst: Montag 1. Oktober 2012, 06:55
von Steffo
OK, danke. Ich werde mir das mal genauer anschauen! :)

L. G.
Steffo