首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python中的CLI Twitter客户端

Python中的CLI Twitter客户端
EN

Code Review用户
提问于 2016-03-10 08:02:48
回答 2查看 154关注 0票数 7

下面是我基于Python中的twitter库编写的Wwitter的一个简单客户机。其目的是能够以轻松的方式从同一个地方从不同的twitter帐户读取提要。

我应该提一下,代码可以做我想做的事情。不过,我怎样才能改善呢?

(它可在GitHub上使用。)

代码语言:javascript
复制
#!/usr/bin/python

import sys
import os
import getopt
from twitter import *

# Default values
def_counts = 10
users = []
dir_creds = "./data/oauth/"

# input parameters
def usage():
  print "Run: " + sys.argv[0] + " [OPTIONS]"
  print "Where OPTIONS is one the following: "
  print " -h --help"
  print " -c N --counts=N"
  print " -u \"name\" --user=\"name\""
  print " -a --all"
  print " -l --list"

def main(argv):
  global def_counts, users
  try: 
    opts, args = getopt.getopt(argv,"hc:u:al",["help","counts=","user=","all","list"])
  except getopt.GetoptError:
    usage()
    exit(2)
  for opt,arg in opts:
    if opt in ["-h","--help"]:
      usage()
      exit(1)
    elif opt in ["-c","--counts"]:
      print "Retrieving "+str(arg)+" tweets."
      def_counts = arg
    elif opt in ["-u","--user"]:
      print "User: "+arg
      users.append(arg)
    elif opt in ["-a","--all"]:
      print "all users"
      if os.path.exists(os.path.expanduser(dir_creds)):
        token_files = filter(lambda x: x.endswith('.token'), os.listdir(os.path.expanduser(dir_creds)))
        for file in token_files:
          usr = file[:file.index(".token")]
          users.append(usr)
      else:
        print "No user to be added, path undefined"
        exit(2)
    elif opt in ["-l","--list"]:
      if os.path.exists(os.path.expanduser(dir_creds)):
        token_files = filter(lambda x: x.endswith('.token'), os.listdir(os.path.expanduser(dir_creds)))
        for file in token_files:
          usr = file[:file.index(".token")]
          print usr
    else:
      print "Got the following and I don't know what to do with it:"
      print opt + " " + arg
      usage()
      exit(2)


if __name__ == "__main__":
  main(sys.argv[1:])

if len(users) < 1:
  users.append("bilbo_pingouin")

col_bgred   = '\033[41m'
col_bold    = '\033[1m'
col_fgblue  = '\033[34m'
col_fggreen = '\033[32m'
col_fggrey  = '\033[90m'
col_end     = '\033[0m'

for user in users:
  print "\n" + col_bgred + col_bold + user + col_end
  # Retrieve the credentials for a given account
  if not os.path.exists(dir_creds):
    os.makedirs(dir_creds) # I just assume there is not race issue here!

  file_creds = dir_creds + user + ".token"
  MY_TWITTER_CREDS = os.path.expanduser(file_creds)

  api_token_file = "data/api_token.dat"
  if os.path.exists(api_token_file):
    cust_token, cust_secret =     read_token_file(os.path.expanduser(api_token_file))
  else:
    print "ERROR: The app is not identified!"

  if not os.path.exists(MY_TWITTER_CREDS):
    oauth_dance("Twit on CLI",cust_token,cust_secret,
            MY_TWITTER_CREDS)

  oauth_token, oauth_secret = read_token_file(MY_TWITTER_CREDS)

  # OAuth idnetification
  t = Twitter(auth=OAuth(oauth_token,oauth_secret,cust_token,cust_secret))

  # Get status
  data = t.statuses.home_timeline(count=def_counts)

  # Print lines
  for c in range(len(data)):
    print "* " + col_fggreen+col_bold+data[c]['user']['name']+col_end + ' (' + col_fgblue+data[c]['user']['screen_name']+col_end + ')' + " - " + data[c]['text'] + col_fggrey+" ## "+data[c]['created_at']+col_end
EN

回答 2

Code Review用户

发布于 2016-03-10 12:16:55

对于刚开始使用Python 3的人来说,或者至少与它兼容是个好主意。这意味着所有print调用都应该使用函数形式,即print(...)

接下来,看看PEP8,并使用四个空格进行缩进。

使用argparse解析命令行参数要好一些,但是既然您已经完成了它,那么重写该部分可能就没有什么意义了。

对于"--all""--list"的情况,也有重复的地方,这样就可以更好地使用一个通用函数。

颜色定义可以从某些模块中提取,例如查看termcolorcolorama

最后,for c in range(len(data)):总是应该被直接迭代所取代的模式,即for x in data:。这句话也很容易读懂。

票数 3
EN

Code Review用户

发布于 2016-03-12 02:05:23

首先,让我们看一下这里的论证解析。

您当前的参数解析代码是..。一塌糊涂。类似于:

代码语言:javascript
复制
import argparse

def main(argv):
    global def_counts, users
    parser = argparse.ArgumentParser(description='Twitter app')
    parser.add_argument('-c', '--counts', help='Count of tweets to retrieve.', required=True)
    parser.add_argument('-u', '--user', help='Username', required=True)

    parser.add_argument('-a', '--all', help='All Users', required=False)
    parser.add_argument('-l', '--list', help='List', required=True)

允许你更灵活地阅读你的论点。你可能会注意到这是..。配置比当前解析容易得多。对像我这样的人来说,阅读也更容易。

这允许您在至少有一个必需的参数并去掉这样做是为了“帮助”选项方法的情况下使用usage

代码语言:javascript
复制
try:
    options = parser.parse_args()
except:
    parser.print_help()
    sys.exit(0)

如果没有提供必需的args,它将抛出一个异常并打印帮助(它将在-h-help--foo-nicorn上这样做)。

这简化了您对args的解析:

代码语言:javascript
复制
def_counts = options['counts']
user = options['user']
users.append(user)

注意,在创建字符串时,以下内容的可读性要高得多:

代码语言:javascript
复制
print "Retrieving {count} tweets.".format(count=def_counts)
print "User: {user}".format(user=user)

特别是当您有更长的字符串时,例如在代码的末尾,使用format和变量作为参数要清楚得多。

您可能会注意到,除了打印或附加之外,listall的解析几乎是相同的。我再次使用您的选项重写了它(请注意,未提供的arg用于arg解析是None,因此您可以执行if arg:来检查参数):

代码语言:javascript
复制
if options['all'] or options['list']:
    print "all users"
    if os.path.exists(os.path.expanduser(dir_creds)):
        token_files = filter(lambda x: x.endswith('.token'), os.listdir(os.path.expanduser(dir_creds)))
        for f in token_files:
            usr = f[:f.index(".token")]
            if options['all']:
                users.append(usr)
            else:
                print usr     
    else:
        print "No user to be added, path undefined"
        exit(2)

我还将file更改为f,因为file是Python中的关键字。

这消除了相当多的重复,并使阅读您的逻辑少得多痛苦。

这里的所有内容都应该重现您的逻辑解析您的args当前的情况(完全免责声明:现在是星期五晚上和.无保证:-)。

对于辣椒8/flake8,您通常也希望在逗号后面添加空格。

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/122449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档