Problem mit Variable

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
nyma3
User
Beiträge: 10
Registriert: Montag 12. November 2018, 12:36

Ich bin mir jetzt nicht sicher ob es so gehört:

Code: Alles auswählen

def check_email():
    server = imaplib.IMAP4_SSL(HOST)
    try imaplib.IMAP4_SSL(HOST) as server:
        print('Logging into', HOST)
        ...
oder so:

Code: Alles auswählen

    
    def check_email():
    server = imaplib.IMAP4_SSL(HOST)
    try:
    with imaplib.IMAP4_SSL(HOST) as server:
        print('Logging into', HOST)
        ...
        
Das finally habe ich jetzt an dieser stelle stehen:

Code: Alles auswählen

            if date_tuple:
                local_message_date = (
                    datetime.datetime
                        .fromtimestamp(email.utils.mktime_tz(date_tuple))
                        .strftime('%a, %d %b %Y %H:%M:%S')
                )
    finally:
    server.logout()
            else:
                local_message_date = '-/-'
            for part in email_message.walk():
                if part.get_content_type() == 'text/plain':
            ...
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nyma3: Weder noch. Wie es korrekt ist habe ich in Worten beschrieben und Sirius3 hat es als Code gezeigt.

Wo in der Dokumentation von ``try`` und ``finally`` und ``with`` bist Du denn auf diese beiden falschen Varianten gestossen? Lies doch einfach mal nach was diese Sprachkonstrukte machen, statt zu raten wie der Code vielleicht aussehen müsste, den Du offenbar nicht verstehst.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
nyma3
User
Beiträge: 10
Registriert: Montag 12. November 2018, 12:36

Nach einigen anderen Foren und Beschreibungen in anderen Foren habe ich nun mehr oder weniger eine Ahnung was try, finally und with machen sollen ..

ich habe jetzt auch with ersetzt und es dahingehend geändert.
Was ich aber leider noch nicht herausgefunden habe ist wo es geschlossen wird und wo ich demnach das finally platzieren soll..

Selbst Versuche haben mich da nicht weitergebracht ..

hier mein derzeitiger Stand:

Code: Alles auswählen

#!/usr/bin/python
from __future__ import absolute_import, division, print_function
import datetime
import email
import imaplib
import time

SENDER = 'xxxx@gmail.com'
EMAIL_ACCOUNT = 'xxxxxx@gmail.com'
PASSWORD = 'xxxxxx'
HOST = 'imap.gmail.com'
MAILBOX = 'inbox'
EXPECTED_SUBJECT = 'CORRECT'
CHECK_DELAY = 3  # in seconds.
MAX_ERROR_COUNT = 10

def check_email():
    server = imaplib.IMAP4_SSL(HOST)
    try:
        print('Logging into', HOST)
        server.login(EMAIL_ACCOUNT, PASSWORD)
        server.select(MAILBOX)
        _, data = server.uid(
            'search', None, '(UNSEEN FROM "{0}")'.format(SENDER)
        )
        for uid in data[0].split():
            _, data = server.uid('fetch', uid, '(RFC822)')
            # 
            # FIXME Decoding seems to be dangerous as the complete
            #   RFC822 message could contain message parts in different
            #   encodings or even binary data that's not supposed to be
            #   decoded as text at all.
            # 
            email_message = email.message_from_string(
                data[0][1].decode('utf-8')
            )
            date_tuple = email.utils.parsedate_tz(email_message['Date'])
            if date_tuple:
                local_message_date = (
                    datetime.datetime
                        .fromtimestamp(email.utils.mktime_tz(date_tuple))
                        .strftime('%a, %d %b %Y %H:%M:%S')
                )
            else:
                local_message_date = '-/-'
            for part in email_message.walk():
                if part.get_content_type() == 'text/plain':
                    file_name = 'email_{}.txt'.format(uid)
                    with open(file_name, 'a') as output_file:
                        #
                        # FIXME Writing a unicode string without
                        #   encoding it will blow up if there is
                        #   anything outside ASCII in it.
                        # 
                        output_file.write(
                            u'From: {}\n'
                            u'To: {}\n'
                            u'Date: {}\n'
                            u'Subject: {}\n\n'
                            u'Body:\n\n{}'.format(
                                email_message['From'],
                                email_message['To'],
                                local_message_date,
                                email_message['Subject'],
                                #
                                # FIXME Message payload can be any
                                #   other encoding.  Hard coding UTF-8
                                #   is wrong.
                                # 
                                part.get_payload(decode=True).decode('utf-8'),
                            )
                        )


def main():
    error_count = 0
    while error_count < MAX_ERROR_COUNT:
        print('establishing connection to ...', HOST)
        try:
            # 
            # FIXME `check_email()` currently doesn't return anything
            #   and also processes potentially no message at all or
            #   even more than one e-mail message.
            # 
            email_message = check_email()
        except IndexError:
            error_count += 1
        else:
            if email_message['Subject'] == EXPECTED_SUBJECT:
                print(
                    '- - -   S U B J E C T   C O R R E C T,'
                    ' (message accepted)   - - -'
                )
            else:
                print(
                    '- - -   S U B J E C T   W R O N G,'
                    ' (message declined)   - - -'
                )
        time.sleep(CHECK_DELAY)
    print('Something went wrong!', MAX_ERROR_COUNT, 'times.')
if __name__ == '__main__':
    main()

Ich wäre für jeden Ratschlag dankbar wie ich das Problem lösen kann ..

im Augeblick bekomme ich folgende Fehlermeldung beim Ausführen des Skripts wenn eine entsprechende Email im Postfach liegt

Code: Alles auswählen

  File "./test3.py", line 75
    def main():
    ^
IndentationError: unexpected unindent
Benutzeravatar
pillmuncher
User
Beiträge: 1482
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

In Zeile 19 steht ein try. Zu einem try-Statement gehört mindestens ein except-Block. Wo ist der?
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Naja, mindestens ein ``except`` *oder* ``finally``. Und um letzteres geht's. Wie das generelle Muster von ``with`` nach ``try``/``finally`` aussehen muss hat Sirius3 ja bereits auf der vorherigen Seite des Themas gezeigt. Die Dokumentation zu ``with`` verweist auf das entsprechende PEP und da steht auch beschrieben wie man das ``with`` durch ”herkömmliche” Sprachkonstrukte ersetzen kann und wie es funktioniert.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
nyma3
User
Beiträge: 10
Registriert: Montag 12. November 2018, 12:36

Nur so mal als Zwischenfrage ..

Mit PEP meinst du das hier:

https://www.python.org/dev/peps/pep-0343/

oder ??
Antworten