2013-12-18 61 views
1

我是這個全新的,所以請忍受我的缺乏理解。從文本文件中使用線作爲功能的數據

我想要ulitmatley做的是從文件中獲取一行文本,然後將其放入一個url(已經有該代碼並理解),這將給出結果。加載後需要刪除文本文件中的值。這是迄今爲止我所知道的,它是一個腳本,它使用instagram API來查找instagram照片。

import time, random 
import urllib,json,urllib2 

def getuserId(userId): 
userId_Dict = {} 
try: 
    list_of_users = open('superlikelist.txt', "r") 
    for line in list_of_users: 
     print line 

    return userIdlist 

我稍後會使用定義的值此

def userspics(userId): 
numuserspics=0 
urlUserMedia = "https://api.instagram.com/v1/users/%s/media/recent/?access_token=%s" % (getuserId,auth_token) 
values = { 
      'client_id' : client_id}  
try: 
    print urlUserMedia 
    data = urllib.urlencode(values) 
    req = urllib2.Request(urlUserMedia,None,headers) 
    response = urllib2.urlopen(req) 
    result = response.read()      
    dataObj = json.loads(result); 
    picsForUser = random.randint(1, 3) 
    print "Pics for user %s" % (picsForUser, userId) 
    countPicViews=0 
    for picture in dataObj['data']: 
     countPicViews = countPicViews+1 
     numLikesFollows = numLikesFollows+1 
     if(countPicViews == picsToLike): 
      break 
except Exception, e: 
    print e 

回答

1

從文本文件的開頭刪除行的唯一方法是重寫整個文件,跳過該行。你可以用Python來做到這一點,或者使用外部工具(如sed),但無論你做什麼,這都會發生。


正如Eli所說,首先將項目複製到某種允許隨機訪問修改的格式會好得多。例如,您可以使用dbm數據庫。 (當然,一個dbm像字典一樣,不喜歡一組......但你總是可以模擬一組與無意義的值的字典。)

首先,使用這個腳本的純文本文件轉換成一個數據庫:

from contextlib import closing 
import dbm 
db = dbm.open('superlikelist.db', 'n') 
with open('superlikelist.txt') as f, closing(db): 
    for line in f: 
     dbm[line] = '' 

現在,你可以這樣做:

from contextlib import closing 
import dbm 

def process_everything(): 
    db = dbm.open('superlikelist.db', 'w') 
    with closing(db): 
     for url in db.keys(): 
      do_something_with(url) 
      del db[url] 

另一種選擇,如果你堅持要用一個文本文件,是爲了避免在重寫文件而不是隻跟蹤在單獨的地方閱讀的最後一行號碼。就像這樣:

def process_file(): 
    try: 
     with open('lastread.txt') as lr: 
      lastread = int(lr.read()) 
    except: 
     lastread = -1 
    with open('superlikelist.txt') as f: 
     for i, line in enumerate(file): 
      if i > lastread: 
       do_stuff_with(line) 
       with open('lastread.txt', 'w') as lr: 
        lr.write(str(lastread)) 

如果必須改寫原來的文件由於某些原因,你至少可以避免重寫它的每一行,而不是僅僅在過程結束重寫一次。顯然你要確保這種情況發生,即使這個過程結束時,比如說,當你只完成一半時,用戶擊中了控制器C,但你可以用try/finallyatexit來處理。 (當然,如果有人在計算機上拔插頭,這將無濟於事......但如果有人在重寫整個文件時拔出了插頭,則會出現問題,並且這種更改會導致該問題不太可能。)所以:

import os 

def process_file(): 
    with open('superlikelist.txt') as f: 
     try: 
      for line in f: 
       do_stuff_with(line) 
     finally: 
      with open('superlikelist.new', 'w') as fout: 
       fout.writelines(f) 
      os.rename('superlikelist.new', 'superlikelist.txt') 

這是一個有點hacky的實現。首先,您可能想要使用tempfile.NamedTemporaryFile而不是硬編碼名稱。其次,在Windows上,如果兩個文件中的任何一個都打開,則不能將一個文件移動到另一個文件上;事實上,真的沒有什麼好的方法來「原子地」替換文件。您可以做的最好的方法是跟蹤臨時文件的名稱,然後在儘快關閉這兩個文件之後,儘快os.remove('superlikelist.txt')然後執行rename

0
  1. 我不建議這樣做,讓。這不是文件IO應該用於的。讀取隊列或數據庫中的項目並在處理每個項目時刪除它們會更好。
  2. 如果你必須這樣做,事情會變得有點混亂,絕對不是pythonic,但它會工作。

做這樣的事情:

f = open('superlikelist.txt', 'rw') 
first_line = f.readline() 
#remove one line from file. 
os.system("sed -i -e '1d' " + f) 

類似的討論here

+0

「開放」模式應該是「r」而不是「rw」。另外,你需要關閉文件(或者,最好使用'with'語句)。另外,你真的應該使用'subprocess',而不是'os.system'。實際上,除非你故意讓你的代碼不能在Windows上工作,否則沒有理由在Python中使用'sed'。 – abarnert

相關問題