首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将最新的堆栈夜间构建的内容附加到全局阴谋配置文件中。

将最新的堆栈夜间构建的内容附加到全局阴谋配置文件中。
EN

Code Review用户
提问于 2015-07-04 14:33:20
回答 3查看 87关注 0票数 4

我制作了下面的python脚本来将最新的堆栈夜间构建的内容附加到全局的cabal配置文件中(而不是到站点,复制页面并手动添加.)。我很感谢你的反馈:

代码语言:javascript
复制
"""
Appends the latest stackage nightly sources from Stackage(http://www.stackage.org/nightly)
to your global cabal config file

It also makes two backups: one of the appended file and one of the unappended file

Stackage(http://www.stackage.org/) is a stable source of Haskell packages
"""

import requests
import shutil
from os.path import expanduser
from os.path import join

cabal_config_path = expanduser('~/.cabal/config')
stackage_nightly_url = 'https://www.stackage.org/nightly/cabal.config?global=true'

def write_cabal_config_backup(filename):
    """ 
    Writes a backup of the current global cabal config file in the ~/.cabal directory
    """
    shutil.copyfile(cabal_config_path, 
        join(expanduser('~/.cabal'), filename))

def unappend_stackage():
    """
    Unappend stackage sources from the global cabal config file. Be careful that 
    the sources must be at the end of the file, or this function will delete things 
    that you don't want it to.
    """
    def unappended_cabal_config():
        # Searches for the string 'Stackage' and returns a list made of the lines
        # of the file from there up, excluding the 'Stackage' line and everything below.
        with open(cabal_config_path) as f:
            cabal_config = f.readlines()
            for i in range(len(cabal_config)):
                if 'Stackage' in cabal_config[i]:
                    return cabal_config[:i]
        return cabal_config
    def write_unappended_cabal_config():
        cabal_config = unappended_cabal_config()
        with open(cabal_config_path, 'wt') as f:
            for line in cabal_config:
                f.write(line)
    write_unappended_cabal_config()

def append_stackage_nightly():
    """
    Appends stackage nightly sources to the global cabal config file
    """
    def get_stackage_nightly():
        r = requests.get(stackage_nightly_url)
        if r.status_code == 200:
            return r.text
    stackage_nightly = get_stackage_nightly()
    if stackage_nightly:
        with open(cabal_config_path, 'a') as f:
            f.write(stackage_nightly)

if __name__ == '__main__':
    write_cabal_config_backup('config_backup_appended')
    unappend_stackage()
    write_cabal_config_backup('config_backup_unappended')
    append_stackage_nightly()
EN

回答 3

Code Review用户

回答已采纳

发布于 2015-07-04 16:30:03

使用生成器可以使unappend_cabal_config更高效、更优雅:

  • 当您可能只需要文件中的行时,从文件中读取所有行,直到其中一行包含“堆栈”才是浪费。
  • 如果可能的话,最好避免循环中的索引变量

如下所示:

代码语言:javascript
复制
def unappend_cabal_config():
    with open(cabal_config_path) as fh:
        for line in fh:
            if 'Stackage' in line:
                return
            yield line
票数 3
EN

Code Review用户

发布于 2015-07-04 17:34:06

您的代码并不会跟随所有的PEP8

  • 有8行太长了。限制所有行最多79个字符。对于结构限制较少的长文本块(docstring或注释),行长度应限制为72个字符。
  • 此外,您不应该在行尾有空格。‘'def foo():’
  • 就像其他人说的。用两行空白行包围顶层函数和类定义。
  • 您应该避免使用fr之类的名称。
  • 康斯坦斯人应该完全资本化。

此外,还有PEP257

  • 您的文档字符串应该处于‘祈使状态’。
  • 您应该在一行上有一行文档字符串,而不是三行。

此外,您为什么那么喜欢嵌套作用域?

这让我感到困惑,首先,您返回信息,然后检查信息,然后在其上使用“函数”。

代码语言:javascript
复制
def append_stackage_nightly():
    def get_stackage_nightly():
        r = requests.get(stackage_nightly_url)
        if r.status_code == 200:
            return r.text
    stackage_nightly = get_stackage_nightly()
    if stackage_nightly:
        with open(cabal_config_path, 'a') as f:
            f.write(stackage_nightly)

您应该使用if stackage_nightly is not None:,但您可以直接删除它。你说这些函数是“错误的”。如果你把with语句放在一个函数中,那就更有意义了。在这里,我将使它成为一个生成器,这样我们就可以最小化读/写操作。

代码语言:javascript
复制
def append_stackage_nightly():
    result = requests.get(stackage_nightly_url)
    if r.status_code == 200:
        yield result.text

编辑:由于一个错误。

现在,我们可以更改unappend_stackage,使其只写入文件。这样我们就不会先清除文件了。(错误)我们将使其具有可迭代性并将其写入文件。

代码语言:javascript
复制
def unappend_stackage():
    def unappended_cabal_config():
        with open(cabal_config_path) as f:
            cabal_config = f.readlines()
            for i in range(len(cabal_config)):
                if 'Stackage' in cabal_config[i]:
                    return cabal_config[:i]
        return cabal_config
    def write_unappended_cabal_config():
        cabal_config = unappended_cabal_config()
        with open(cabal_config_path, 'wt') as f:
            for line in cabal_config:
                f.write(line)
    write_unappended_cabal_config()

当我们改变了append_stackage_nightly,我们可以循环通过一个生成器。而不是做一个新的。我们会把这个函数去掉,所以它是一个单一的函数。

代码语言:javascript
复制
def unappend_stackage(iterable):
    with open(cabel_config_path, 'wa') as cabel_write:
        for line in iterable:
            if 'Stackage' in line:
                break
                # You may want this to be `continue`,
                # unless you know for sure there is no data after the first Stackage.
            cabel_write.write(line)

这消除了向cabel_config_path写入两次并从中读取一次的需要。

票数 3
EN

Code Review用户

发布于 2015-07-04 16:02:01

这段代码写得很好!我确实有一些关于风格和诸如此类的挑剔的小窍门,所以这里列出了我所看到的所有可以改进的小东西。

  1. 您的两个函数unappended_cabal_configwrite_unappended_cabal_config绝对可以使用docstring。
  2. 在顶级函数之间应该有两个空行,而不是一个。

除此之外,您的代码非常干净和好看!做得好!

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

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

复制
相关文章

相似问题

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