2016-05-16 6 views
0

Ich habe folgende Stand-alone-Funktion für den Druck Argumente:Funktion innerhalb des Objekts unterschiedlicher Druckausgabe als Stand-alone-Funktion in Python zu erzeugen 3.5

def multiArgsPrinter2(*args): 
    testString = ''; 
    for count, thing in enumerate(args): 
     testString += str(thing) + "," 

    return testString 

der, wenn du wie folgt ausführen:

retval = multiArgsPrinter2(20, 30, 40) 
print(retval) 

druckt 20,30,40, - wie erwartet. Ich mache dann eine Klasse mit dieser Funktionalität im Inneren:

class TestHelper2: 
    """The TestHelper Class""" 

    def multiArgsPrinter3(*args): 
     testString = ''; 
     for count, thing in enumerate(args): 
      testString += str(thing) + "," 

     print(testString) 
     return testString 

Egal wo ich dieses Ergebnis zu drucken, entweder als Rückgabewert oder innerhalb der Klasse der Ausgang I sieht wie folgt erhalten:

<TestHelper2.TestHelper2 object at 0x00F6ABB0>,20,30,40, 

die verwirrt mich. Irgendwelche Hinweise auf das, was ich nicht verstehe?

Bonuspunkte, wenn Sie mir sagen können, warum das Aufrufen einer weiteren Funktion in einem Objekt die Anbringung von Klammern() um den Rückgabewert herum verursacht?

+2

Wie für Ihre Bonuspunkte Frage, sollte das eine separate Frage mit einem Beispiel sein, was Sie meinen. So wie es ist, weiß ich nicht wovon du sprichst. –

+0

Ich habe die Bonuspunkte gelöst. Ich übergab fälschlicherweise die Variable 'args' an eine andere Elementfunktion, ohne dass das Sternchen (*) angehängt war, und überließ es im Grunde als Liste und erzeugte schließlich bei der Ausgabe Klammern. – Gazoo

Antwort

2

In einer Klasse definierte Funktionen sind standardmäßig Instanzmethoden. Dies bedeutet, dass sie implizit eine Instanz der Klasse übergeben werden und die Funktionssignatur dies widerspiegeln sollte. Zum Beispiel:

class Example: 
    def print_stuff(self, *args): 
     print 'My *self* is {}'.format(self) 
     print 'My *args* is {}'.format(args) 

Example().print_stuff(1, 2, 3) 
# My *self* is <__main__.Example instance at 0x012D4210> 
# My *args* is (1, 2, 3) 

Python stellt zwei Dekoratore, um die Signatur einer Funktion innerhalb einer Klasse, staticmethod und classmethod definiert zu verändern. Sie werden am häufigsten mit der Decorator-Syntax verwendet (über den Rahmen dieser Antwort hinaus) und sind Funktionen, die eine Funktion als Argument akzeptieren und eine neue, geänderte Funktion zurückgeben.

staticmethod entfernt das implizite self Argument von einer Funktion innerhalb einer Klasse.

class Example: 
    @staticmethod 
    def print_stuff(*args): 
     # No more self... 
     print 'My *args* is {}'.format(args) 

Example().print_stuff(1, 2, 3) 
# My *args* is (1, 2, 3) 

Eine hypothetische Umsetzung staticmethod könnte wie folgt aussehen:

def staticmethod_example(func): 
    def wrapper(self, *args, **kwargs): 
     return func(*args, **kwargs) # Notice how *self* is thrown away 
    return wrapper 

classmethod entfernt das implizite self Argument aus einer Funktion, sondern fügt die Instanz-Klasse als Argument statt.

class Example: 
    @classmethod 
    def print_stuff(cls, *args): 
     print 'My *cls* is {}'.format(cls) 
     print 'My *args* is {}'.format(args) 

Example().print_stuff(1, 2, 3) 
# My *cls* is __main__.Example 
# My *args* is (1, 2, 3) 

Eine hypothetische Umsetzung classmethod könnte wie folgt aussehen:

def classmethod_example(func): 
    def wrapper(self, *args, **kwargs): 
     return func(self.__class__, *args, **kwargs) # Substitute *cls* for *self* 
    return wrapper 

Ihre Frage zu beantworten, wird Ihr Funktionsaufruf die Instanz der Klasse Druck, weil es self implizit übergeben wird. Wenn Sie den Dekorator staticmethod über der Funktionsdeklaration hinzufügen, funktioniert es wie vorgesehen.

+0

Danke für die aufschlussreichen und hilfreichen Antworten. Mein Verstand hat deutlich mehr von Python verloren, als ich dachte. Schätze, es ist passend, dass ich mich selbst erziehe. – Gazoo

3

Das Problem ist, dass multiArgsPrinter3(*args)self in *args gefangen ist. Sie müssen nur die Signatur in multiArgsPrinter3(self, *args) ändern, und es wird funktionieren.

class TestHelper: 
    """"The TestHelper Class""" 
    def multi_args_printer(self, *args): 
     test_string = '' 
     for thing in args: 
      test_string += str(thing) + "," 
     print(test_string) 
     return test_string 

print(TestHelper().multi_args_printer(20, 30, 40)) # Prints "20,30,40," 

Als Seite beachten, es sei denn, Sie das folgende Komma möchten, sollten Sie join verwenden. ZB ','.join(map(str,args)).

+1

Wäre es nicht besser, es zu einer "statischen Methode" zu machen, da es sich um eine statische Methode handelt? Es kann weitere Erläuterungen zu gebundenen Instanzmethoden erfordern, die implizit an die Instanz übergeben werden, aber es ist seltsam, dass eine Instanzmethode die Instanz nicht verwendet. –

+0

@JaredGoguen Sicher, wenn das Produktionscode wäre. So wie es ist, möchte ich das OP nicht mit Dekorateuren und so weiter verwechseln. –

+1

die 'Join' Alternative sollte' ',' sein. Join (map (str, args)) 'weil' join' keine automatische Konvertierung für eine Sache, die keine Zeichenkette ist, machen. – Copperfield

Verwandte Themen