Seite 1 von 1

Problem beim Umstieg von 2.7 auf 3.2 mit functools.partial

Verfasst: Mittwoch 29. Mai 2013, 13:03
von mathi
hallo miteinander,

ich habe im Programm unter Python 2.7 folgendes erstellt (es funktioniert):

Code: Alles auswählen

label2=functools.partial(label,newdir=newdir,newdate=newdate)
unter 2.7 ergibt ein

Code: Alles auswählen

print label2
das Ergebnis

Code: Alles auswählen

<functools.partial object at 0x00000000048ABAE8>
unter 3.2 ergibt das gleiche dann

Code: Alles auswählen

functools.partial(<function label at 0x0000000002E0A840>, newdir='D:\\Projekte\\Bilder\\new', newdate=False)
was mir für die nachfolgende Funktion:

Code: Alles auswählen

            for i in pool.map(label2,([q]*self.anzahl)):       
               self.count+=1
               
dann die Fehlermeldung bringt:
Traceback (most recent call last):
File "D:\Python\Code\pyQT\PySide-Projekt\jpglabel.pyw", line 206, in on_calcbtn_clicked
for i in pool.map(label2,([q]*self.anzahl)):
File "C:\Python33\lib\multiprocessing\pool.py", line 228, in map
return self._map_async(func, iterable, mapstar, chunksize).get()
File "C:\Python33\lib\multiprocessing\pool.py", line 564, in get
raise self._value
AttributeError: 'NoneType' object has no attribute 'dict'
Das ist das Ganze in Kürze. Kann mir dabei bitte jemand helfen??
Falls der Code ausführlicher benötigt wird, kann ich das noch nachreichen :-)

Danke im Voraus
Mathi

Re: Problem beim Umstieg von 2.7 auf 3.2 mit functools.parti

Verfasst: Mittwoch 29. Mai 2013, 13:56
von BlackJack
@mathi: Ich sehe jetzt nicht dass das zwingend an `functools.partial()` liegt. Wie kommst Du darauf?

Re: Problem beim Umstieg von 2.7 auf 3.2 mit functools.parti

Verfasst: Mittwoch 29. Mai 2013, 14:21
von mathi
nun,
ich versuche das skript von 2.7 nach 3.2 zu portieren...
- die 3 Parameter label,newdir und newdate, die an functools übergeben werden, enthalten die gleichen Informationen,
- in der Funktion "label" wurde nichts geändert (ein Bild wird geöffnet, bearbeitet/beschriftet und gespeichert)
- und print() liefert trotzdem nicht das Gleiche -- in python 3.2 werden zusätzliche Werte übergeben
->daher meine Annahme

In der Beschreibung zu functools habe ich aber auch nichts von Änderungen gelesen.

Hier mal die Funktion "label", die mit den 2 zusätzlichen Parametern übergeben wurde...

Code: Alles auswählen

def label(q,newdir,newdate):
    while not q.empty():
        pts = -1
        entry=q.get()

        outname = os.path.join(newdir,entry)
        im = Image.open(entry) 
        if newdate==False:
            exif = jpeg.getExif(entry)
            date = exif.dict()['DateTimeOriginal'][2]
            text = '%s.%s.%s' % (date[8:10], date[5:7], date[:4])
        else:
            text=newdate
        fac = max(im.size) / 3000.0
        newpts = int(fac * 48)
        if pts != newpts:
            pts = newpts
            x = int(fac * 2700)
            y = int(fac * 80)
            font = ImageFont.truetype('arial.ttf', newpts)
        draw = ImageDraw.Draw(im)
        y = im.size[1] - y
        w, h = draw.textsize(text, font=font)
        crop_old = im.crop((x - 1, y - 1, x + w + 1, y + h + 1))
        var_old = sum(ImageStat.Stat(crop_old).var)
        #Mit Schwarz beginnen
        text_col = 0
        #Bis einschließlich Weiß wiederholen
        while text_col <= 0xFFFFFF:
            draw.text((x, y), text, font=font, fill=text_col)
            crop_new = im.crop((x - 1, y - 1,
                                x + w + 1, y + h + 1))
            var_new = sum(ImageStat.Stat(crop_new).var)
            if var_new - var_old > 5000:
                break
            text_col += 0x010101
        else:
            print('Kontrast nicht ausreichend -', end=' ')
            #self.error_flag = True
        if not os.path.isdir(newdir):
            os.mkdir(newdir)
        im.save(outname)
        # Change the date
        jpeg.setExif(exif, outname) 
Daher war ich der Meinung functools ist schuld.
unter 2.7 wird ein "Objekt" übergeben (die Speicheradresse) und unter 3.2 eben nicht, daher der AttributeError oder??

Re: Problem beim Umstieg von 2.7 auf 3.2 mit functools.parti

Verfasst: Mittwoch 29. Mai 2013, 15:25
von BlackJack
@mathi: Sowohl in Python 2 als auch in Python 3 wird ein Objekt übergeben und keine Speicheradresse. Das was Du mit ``print`` bekommst ist eine Zeichenkettendarstellung des Objekts welche das Objekt selbst liefert. Da kann alles mögliche drin stehen. Das einzige was man an dieser Änderung sehen und mit Sicherheit sagen kann, ist dass sich die `__str__()` oder die `__repr__()`-Methode von diesen Objekten geändert hat, und beide haben ansonsten keinen Einfluss auf das Verhalten von Objekten.

Die Fehlermeldung sagt aus, dass auf einem Objekt vom Typ `NoneType`, also einem `None`-Wert kein Attribut mit dem Namen `dict` existiert. Nun schau doch mal in Deiner `label()`-Funktion wo da auf ein `dict`-Attribut zugegriffen wird. Offensichtlich gibt ``jpeg.getExif(entry)`` unter bestimmten Umständen `None` zurück.

Mit der `q` gehst Du übrigens unsicher um. Wenn die Bedingung der ``while``-Schleife wahr ist, heisst das ja nicht, dass sie das wenn kurz danach `get()` aufgerufen wird, immer noch ist. Da kann die Schleife dann hängen bleiben.

Re: Problem beim Umstieg von 2.7 auf 3.2 mit functools.parti

Verfasst: Donnerstag 30. Mai 2013, 20:11
von mathi
vielen Dank für die Hilfe, da hätte ich ja lange suchen können.
Hattest vollkommen recht, es lag an einem nicht kompatiblen modul :-)

Problem gelöst :)
das mit der "while"-Schleife schaue ich mir noch an, danke

Gruß Mathi