質問

I'm learning Python and as a learning project, I'm developing a twitter bot. I'm using Python 3. I use the following lines for tweets.

What is Bruce Lee’s favorite drink? Wataaaaah!
The dyslexic devil worshipper sold his soul to Santa.
You kill vegetarian vampires with a steak to the heart.
There was a prison break and I saw a midget climb up the fence. As he jumped down he sneered at me and I thought, well that’s a little condescending.

This is my code that uses Twython to tweet:

from twython import Twython, TwythonError
import time

APP_KEY = '##########'  # Customer Key here
APP_SECRET = '#############'  # Customer secret here
OAUTH_TOKEN = '###############'  # Access Token here
OAUTH_TOKEN_SECRET = '################'  # Access Token Secret here

twitter = Twython(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)

try:
    with open('jokes.txt', 'r+') as file:
        buff = file.readlines()

    for line in buff:
        if len(line)<140:
            print ("Tweeting...")
            twitter.update_status(status=line)
            time.sleep(3)
            with open ('jokes.txt', 'r+') as file:
                buff.remove(line)
                file.writelines(buff)
        else:
            with open ('jokes.txt', 'r+') as file:
                buff.remove(line)
                file.writelines(buff)
            print ("Skipped line - Char Length Violation")
            continue


except TwythonError as e:
    print (e)

I wanted to skip the lines that has over 140 characters with a message on the console Skipped line - Char Length Violation and then remove that particular line and update the file. The script successfully tweets by ignoring the line, but fails printing the console message. It also fails to remove the line from the text file.

I have no idea why the third line You kill vegetarian vampires with a steak to the heart.was skipped.

What's wrong with my code and why my text file looks like this after I run the script:

The dyslexic devil worshipper sold his soul to Santa.
There was a prison break and I saw a midget climb up the fence. As he jumped down he sneered at me and I thought, well that’s a little condescending.d at me and I thought, well that’s a little condescending.nd I thought, well that’s a little condescending.

役に立ちましたか?

解決

First, try to avoid using file to name your variable, as it's a reserved keyword in Python used for the type file.

The fixed code:

from twython import Twython, TwythonError
import time

APP_KEY = '##########'  # Customer Key here
APP_SECRET = '#############'  # Customer secret here
OAUTH_TOKEN = '###############'  # Access Token here
OAUTH_TOKEN_SECRET = '################'  # Access Token Secret here

twitter = Twython(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)

try:
    with open('jokes.txt', 'r+') as fp:
        buff = fp.readlines()

    for line in buff[:]:
        if len(line) < 140:
            print("Tweeting...")
            twitter.update_status(status=line)
            time.sleep(3)
            with open('jokes.txt', 'w') as fp:
                buff.remove(line)
                fp.writelines(buff)
        else:
            with open('jokes.txt', 'w') as fp:
                buff.remove(line)
                fp.writelines(buff)
            print("Skipped line - Char Length Violation")
            continue


except TwythonError as e:
    print(e)

Usually - like in this case - it's not a good idea to modify your iterable (list) inside a cycle which iterates on the same iterable. The trick here is the slicing operator in the line for line in buff[:]: which makes a copy of your buff list, and iterates on the copy instead of the original buff list.

Also, when you'd like to overwrite a file, you must open it in 'w' mode, not in 'r+' mode, because 'r+' won't truncate your file first.

他のヒント

file.close()

seems to be misplace under the with ... as file: block. The advantage of with is that you don't need to do this bookkeeping.

In the else block the file object is close, so file.writelines() should raise an exception.

As far as I can see is buff a string and therefore immutable. You might want to try buff = buff.remove(...), but does it even have the remove method?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top