2017-01-30 1 views
1

Nehmen Sie das folgende vereinfachte Beispiel.Wie übergeben Sie Argumente an die Python-Funktion, deren erster Parameter self ist?

class A(object): 
    variable_A = 1 
    variable_B = 2 

    def functionA(self, param): 
     print(param+self.variable_A) 

print(A.functionA(3)) 

Im obigen Beispiel, bekomme ich folgende Fehler

Traceback (most recent call last): 
    File "python", line 8, in <module> 
TypeError: functionA() missing 1 required positional argument: 'param' 

Aber, wenn ich die self, in der Funktionsdeklaration zu entfernen, bin ich nicht in der Lage, die Variablen für den Zugriff auf variable_A und variable_B in dem Klasse, und ich bekomme folgende Fehlermeldung

Traceback (most recent call last): 
    File "python", line 8, in <module> 
    File "python", line 6, in functionA 
NameError: name 'self' is not defined 

Also, wie greife ich auf die Klassenvariablen und nicht den param Fehler hier? Ich benutze Python 3 FYI.

+2

'A' ist eine Klasse. Sie benötigen 'A()' (Instanz von 'A'). – vaultah

Antwort

5

Sie müssen zuerst eine Instanz der Klasse erstellen A

class A(object): 
    variable_A = 1 
    variable_B = 2 

    def functionA(self, param): 
     return (param+self.variable_A) 


a = A() 
print(a.functionA(3)) 

Sie static Dekorateur verwenden können, wenn Sie nicht über eine Instanz verwenden möchten. Statische Methoden sind ein Spezialfall von Methoden. Manchmal schreiben Sie Code, der zu einer Klasse gehört, aber das Objekt selbst wird überhaupt nicht verwendet.

class A(object): 
    variable_A = 1 
    variable_B = 2 

    @staticmethod 
    def functionA(param): 
     return (param+A.variable_A) 

print(A.functionA(3)) 

Eine andere Möglichkeit ist die Verwendung von classmethod decorator. Klassenmethoden sind Methoden, die nicht an ein Objekt gebunden sind, sondern an eine Klasse!

class A(object): 
    variable_A = 1 
    variable_B = 2 

    @classmethod 
    def functionA(cls,param): 
     return (param+cls.variable_A) 

print(A.functionA(3)) 
+1

Sie hätten auch eine 'Klassenmethode' verwenden können –

+0

Dies ist eine technisch korrekte Antwort, aber sie erklärt nichts ... –

1

Erstellen Sie zuerst ein Objekt von A.

a = A() 
a.functionA(3) 
2

functionA In Ihrem Code oben ist eine Instanzmethode. Du gibst "Selbst" nicht direkt an es weiter. Stattdessen müssen Sie eine Instanz erstellen, um sie verwenden zu können. Das "self" -Argument der Funktion ist in der Tat die Instanz, an der es aufgerufen wird. Zum Beispiel:

a = A() 
a.functionA(3) 

P.S. Beachten Sie, dass Ihre functionAprint aufruft, aber nichts zurückgibt, dh sie gibt implizit None zurück. Sie sollten es entweder einen Wert zurückgeben lassen und es vom Anrufer ausdrucken, oder, wie ich oben getan habe, es anrufen und es selbst drucken lassen.

+0

O das war einfach. Danke für die Erklärung. Kannst du mir auch sagen, warum es die Funktion aufrufen konnte, ohne ein Objekt zu erstellen? Funktionierte es als statische Funktion oder etwas? –

+1

Eine Funktion "die selbst als erstes Argument annimmt" (=> deren erstes Argument "self" heißt) ist eine Funktion, deren erstes Argument zufällig "self" heißt. Das macht es nicht zu einer Instanzmethode. Was es zu einer Instanzmethode macht, ist ein Attribut einer Klasse, das nach einer Instanz dieser Klasse gesucht wird. Lesen Sie dies: https://wiki.python.org/moin/FromFunctionToMethod für mehr über die Inners. –

+0

@brunodesthuilliers arg, das war extrem schlecht formuliert, stimme ich zu. Ich werde versuchen, dies zu bearbeiten und zu korrigieren. – Mureinik

1

Wenn ein Funktionsobjekt (was die def Anweisung erstellt) ein Attribut einer Klasse und nachgeschlagen auf der Klasse oder eine Instanz der Klasse (das obj.attrname Schema verwendet wird), wird es in ein method gedreht Objekt. Dieses method Objekt ist selbst abrufbar. Wenn das Nachschlagen auf einer Instanz geschieht, wird diese Instanz "magisch" als erstes Argument in die Funktion eingefügt. Wenn nicht, müssen Sie es selbst bereitstellen (genau wie bei jedem anderen Argument).

Sie können mehr über diese lesen (und wie die „Magie“ geschieht hier: https://wiki.python.org/moin/FromFunctionToMethod

In Ihrem Fall Nachschlag Sie die Funktion auf der Klasse, so dass es zwei Argumente erwartet (self und param), aber Sie nur passieren param, daher der Fehler.

Sie haben variable_A und variable_B als Klassenattribute definiert (Attribute, die von allen Instanzen der Klasse gemeinsam genutzt werden). Wenn das wirklich die Absicht ist, und Sie wollen eine Methode, die Sie auf die Klasse selbst aufrufen können und die auf Klassenattribute zugreifen können, können Sie functionA eine machen (es funktioniert das gleiche wie eine "Instanz" -Methode, außer es ist die Klasse, die als erstes Argument eingefügt) wird ‚magisch‘:

class A(object): 
    variable_A = 1 
    variable_B = 2 

    @classmethod 
    def functionA(cls, param): 
    return param + cls.variable_A 

Dann können Sie functionA rufen entweder direkt auf die Klasse selbst:

print(A.functionA(42)) 

oder auf einer Instanz, wenn Sie bereits eine zur Hand haben:

a = A() 

# ... 

print(a.functionA(42)) 

Nun, wenn Sie wirklich variable_A und variable_B wollten Attribut pro Instanz sein (jede Instanz A hat es ganz eigene Variablen), müssen Sie diese Attribute auf der Instanz selbst in der initialier Methode und 2/Aufruf zu 1/erstellen functionA auf einigen A Instanz, dh:

class A(object): 
    def __init__(self, variable_A=1, variable_B=2): 
     self.variable_A = variableA 
     self.variable_B = variableB 

    def functionA(self, param): 
    return param + self.variable_A 



a1 = A() # using default values 
print(a1.functionA(42)) 

a2 = A(5) # custom value for variable_A 
print(a2.functionA(42)) 
Verwandte Themen