python3.x - 有人能帮我看下能跑但不优雅的python代码吗?包括测试代码与换行只有70行

查看:184
本文介绍了python3.x - 有人能帮我看下能跑但不优雅的python代码吗?包括测试代码与换行只有70行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

main.py

import os
import time
from zhihu_oauth import ZhihuClient
import html2text

_h = html2text.HTML2Text()

layout_format = {}

for filename in os.listdir('mod'):
    if filename.endswith('py'):
        exec(open(os.path.join('mod', filename)).read())

print(layout_format)

def format_date(unix_timestamp_str):
    return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(unix_timestamp_str)))

class ZhihuParser:
    def __init__(self, answer, layout='md'):
        self.layout = layout
        self.title = answer.question.title
        self.author = answer.author.name
        self.created_time = format_date(answer.created_time)
        self.updated_time = format_date(answer.updated_time)
        self.voteup_count = answer.voteup_count
        self.thanks_count = answer.thanks_count
        self.content = answer.content
        self.content = self.__parser()

    def __parser(self):
        return _h.handle(self.content)

    def __str__(self):
        return layout_format.get(self.layout)(self)

    def __getitem__(self, key):
        return eval('self.' + key)


if __name__ == "__main__":
    TOKEN_FILE = 'token.pkl'
    client = ZhihuClient()
    if os.path.isfile(TOKEN_FILE):
        client.load_token(TOKEN_FILE)
    else:
        client.login_in_terminal()
        client.save_token(TOKEN_FILE)
    print(ZhihuParser(client.answer(128260462)))
    exit()

mod/md.py

markdown_template = """# %(title)s
Author: %(author)s
Create Date: %(created_time)s
Last Update: %(updated_time)s

%(content)s
"""

def markdown(self):
    return markdown_template % self

layout_format['md'] = markdown

其中,

def __getitem__(self, key):
    return eval('self.' + key)

这段有更好的写法吗?

以及我想让用户把自己写的mod文件放到mod文件夹下程序自动挂载,实现代码为:

layout_format = {}

for filename in os.listdir('mod'):
    if filename.endswith('py'):
        exec(open(os.path.join('mod', filename)).read())

配合插件中的

layout_format['mod_name'] = mod_function

这样写有啥优化改进的地方吗?欢迎提建议

解决方案

  1. 针对于第一个问题, eval确实不好, 你可以使用getattrsetattr来动态的访问和修改某个对象的属性 (配合__getitem____setitem__这两个魔术方法)

  2. 你其实期望的是一个简单的插件机制, 直接用exec来拿命令行输出也确实是不妥的, 给你一个简单的:

mod/__init__.py

# 空文件(但为了让mod目录成为python的module必须)

mod/demo.py

def init_plugin(*args, **kwargs):
    print args, kwargs

main.py

class plugin_manager:

    plugins = {}

    def load(self, name):
        module = __import__('mod.%s' % name)
        self.plugins[name] = getattr(module, name)
        return self.plugins[name]

    def init_plugin(self, name, *args, **kwargs):
        plugin = self.load(name)
        plugin.init_plugin(*args, **kwargs)
        return plugin


manager = plugin_manager()
manager.init_plugin('demo', 'hello', text1 = 'world', text2='test')

运行输出

('hello',)
{'text2': 'test', 'text1': 'world'}

这篇关于python3.x - 有人能帮我看下能跑但不优雅的python代码吗?包括测试代码与换行只有70行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆