Projeto Python3 remove pastas __pycache__ e arquivos .pyc


166

Qual é a melhor maneira de limpar todas as __pycache__ pastas e .pyc/.pyoarquivos de um projeto python3. Eu já vi vários usuários sugerirem o pycleanscript incluído no Debian, mas isso não remove as pastas. Eu quero uma maneira simples de limpar o projeto antes de enviar os arquivos para o meu DVS.

Respostas:


241

Você pode fazer isso manualmente com o próximo comando:

find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf

Isso removerá todos os arquivos * .pyc e diretórios __pycache__ recursivamente no diretório atual.


8
O comando está sujo. Ele também irá excluir *__pycache__, *.pyc*e não faz distinção entre arquivos e diretórios. A maioria dos rmcomandos gerados também será supérflua.
ivan_pozdeev

12
Isso está errado. Não é assim que você usa findnem grepnem rme pode ser perigoso para qualquer diretório de trabalho atual que possa conter useful.pycle.jsonou important_deployment_setting_about__pycache__.txtetc. O que eu não descartaria em toda a base de usuários do SO. Sem mencionar o quão (perigosamente rm -rf) xargsseria quebrado por um arquivo com espaço em branco no nome. Então eu editei…
dlamblin

@dwanderson Acho que você está falando de uma resposta diferente; ou o SO edita o histórico não mostra mais o histórico completo Por exemplo, houve uma versão em 2017 que não é exibida lá?
dlamblin

2
Não funciona no OSXgrep: parentheses not balanced
Daniel W.

85

Encontrei a resposta quando digitei pyclean como pycclean:

    No command 'pycclean' found, did you mean:
     Command 'py3clean' from package 'python3-minimal' (main)
     Command 'pyclean' from package 'python-minimal' (main)
    pycclean: command not found

Correr py3clean .limpou muito bem.


6
py3clean é mais conservador que o comando @ V.Gamula: não exclui arquivos .pyc gerados a partir de arquivos de origem que foram excluídos desde então.
Jérôme

1
Em maio / 2017, em macos / homebrew, eu tive que usar o pacote pycleaner do pip, e o comando para executá-lo é pycleaner. Somente Python 2.
Willian Mitsuda

3
python3-minimal parece estar disponível apenas no Debian (não o encontra no RHEL, CentOS, brew, MacOS)
user12345

1
Por incrível que pareça, meu py3clean instalado (3.5.1-3) não faz nada realmente, limpa nenhum desses arquivos e simplesmente retorna silenciosamente (python 3.6.5).
matanster

4
Ele não exclui __pycache__pastas, nem .pycarquivos (testado em debian)
EricLavault

82

macOS e Linux

BSD's find implementação no macOS é diferente da localização do GNU - é compatível com a localização do BSD e do GNU. Comece com uma implementação globbing, usando -namee -ofor ou - Coloque esta função no seu .bashrcarquivo:

pyclean () {
    find . -type f -name '*.py[co]' -delete -o -type d -name __pycache__ -delete
}

Em seguida, vá cdpara o diretório que você deseja limpar recursivamente e digite pyclean.

Somente localização GNU

Esta é uma solução GNU find, only (ou seja, Linux), mas acho que é um pouco melhor com o regex:

pyclean () {
    find . -regex '^.*\(__pycache__\|\.py[co]\)$' -delete
}

Qualquer plataforma, usando Python 3

No Windows, você provavelmente nem tem find . No entanto, você provavelmente possui o Python 3, que a partir do 3.4 possui o pathlibmódulo conveniente :

python3 -Bc "import pathlib; [p.unlink() for p in pathlib.Path('.').rglob('*.py[co]')]"
python3 -Bc "import pathlib; [p.rmdir() for p in pathlib.Path('.').rglob('__pycache__')]"

o -B bandeira diz ao Python para não gravar .pycarquivos. (Veja também a PYTHONDONTWRITEBYTECODEvariável de ambiente.)

Os abusos acima listam compreensões para loop, mas ao usar python -c , o estilo é uma preocupação secundária. Como alternativa, podemos abusar (por exemplo) __import__:

python3 -Bc "for p in __import__('pathlib').Path('.').rglob('*.py[co]'): p.unlink()"
python3 -Bc "for p in __import__('pathlib').Path('.').rglob('__pycache__'): p.rmdir()"

Crítica de uma resposta

A resposta principal costumava dizer:

find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf

Isso parece ser menos eficiente porque usa três processos. findusa uma expressão regular; portanto, não precisamos de uma chamada separada de grep. Da mesma forma, tem -delete, por isso, não precisa de uma invocação separada do rmcontrário -e a um comentário aqui, ele vai excluir diretórios não vazios desde que eles se esvaziado em virtude da correspondência de expressão regular.

Na xargspágina do manual:

find /tmp -depth -name core -type f -delete

Localize os arquivos denominados core no diretório / tmp ou abaixo dele e exclua-os, mas com mais eficiência do que no exemplo anterior (porque evitamos a necessidade de usar fork (2) e exec (2) para iniciar a rm e não precisamos do processo extra xargs).


Você provavelmente poderia obter a versão python em uma linha usando shutil.rmteeos __pycache__diretórios em vez de esvaziá-los primeiro; um one-liner pode ser bom para um alias fácil. Eu sou um grande fã de Pathagora, no entanto, então acho que vou usar essa versão no meu script.
21419 Nathan

25

Como este é um projeto Python 3, você só precisa excluir __pycache__diretórios - todos os arquivos .pyc/ .pyoestão dentro deles.

find . -type d -name __pycache__ -exec rm -r {} \+

ou sua forma mais simples,

find . -type d -name __pycache__ -delete

que não funcionou para mim por algum motivo (os arquivos foram excluídos, mas os diretórios não), então estou incluindo os dois por uma questão de integridade.


Como alternativa, se você estiver fazendo isso em um diretório que está sob controle de revisão, poderá solicitar ao RCS que ignore as __pycache__pastas recursivamente. Em seguida, no momento necessário, limpe todos os arquivos ignorados. Isso provavelmente será mais conveniente, porque provavelmente haverá mais para limpar do que apenas __pycache__.


Não, nem todos os .pycarquivos estão dentro dele.
Martin Thoma

@ V.Gamula Este é um comando consideravelmente mais seguro do que aquele que ~ 114 pessoas tiveram a sorte de não os morderem com a exclusão permanente de uma partida equivocada.
precisa saber é o seguinte

@MartinThoma em um projeto somente python3?
dlamblin

4
Eu sou o único a obter Directory not emptya segunda variante aqui?
matanster

13

Este é o meu alias que funciona tanto com o Python 2 quanto com o Python 3, removendo todos os .pyc .pyoarquivos e __pycache__diretórios recursivamente.

alias pyclean='find . -name "*.py[co]" -o -name __pycache__ -exec rm -rf {} +'

Muito obrigado. Isso me ajudou a me livrar de todos os arquivos desnecessários para meus repositórios.
Harsh Aggarwal

13

Se você precisar de uma solução permanente para manter os arquivos de cache Python fora dos diretórios do seu projeto:

A partir do Python 3.8, você pode usar a variável de ambiente PYTHONPYCACHEPREFIXpara definir um diretório de cache para o Python.

Nos documentos do Python:

Se isso estiver definido, o Python gravará arquivos .pyc em uma árvore de diretórios espelhados nesse caminho, em vez de nos diretórios pycache da árvore de origem. Isso é equivalente a especificar a opção -X pycache_prefix = PATH.

Exemplo

Se você adicionar a seguinte linha ao seu ./profileno Linux:

export PYTHONPYCACHEPREFIX="$HOME/.cache/cpython/"

O Python não criará os __pycache__diretórios irritantes no diretório do seu projeto, mas colocará todos eles em~/.cache/cpython/


4
Graças a Deus isso está chegando. Os diretórios do lixo pycache foram um erro.
Sarah G

7

O comando que eu usei:

find . -type d -name "__pycache__" -exec rm -r {} +

Explica:

  1. Primeiro localiza todas as __pycache__pastas no diretório atual.

  2. Execute rm -r {} +para excluir cada pasta na etapa acima ( {} signifique o espaço reservado e finalize +o comando)

Editado 1:

Estou usando o Linux, para reutilizar o comando que adicionei a linha abaixo ao ~/.bashrcarquivo

alias rm-pycache='find . -type d -name  "__pycache__" -exec rm -r {} +'

Editado 2: se você estiver usando o Código VS , não precisará remover __pycache__manualmente. Você pode adicionar o snippet abaixo ao settings.jsonarquivo. Depois disso, o VS Code ocultará todas as __pycache__pastas para você

"files.exclude": {
     "**/__pycache__": true
}

Espero que ajude !!!


4

Usando PyCharm

Para remover arquivos compilados do Python

  1. No Project Tool Window, clique com o botão direito do mouse em um projeto ou diretório, de onde os arquivos compilados Python devem ser excluídos.

  2. No menu de contexto, escolha Clean Python compiled files.

Os .pycarquivos que residem no diretório selecionado são excluídos silenciosamente.


4

No diretório do projeto, digite o seguinte:

Excluindo todos os arquivos .pyc

find . -path "*/*.pyc" -delete

Excluindo todos os arquivos .pyo :

find . -path "*/*.pyo" -delete

Por fim, para excluir todos os '__pycache__' , digite:

find . -path "*/__pycache__" -type d -exec rm -r {} ';'

Se você encontrar um erro de permissão negada , adicione sudo no início de todo o comando acima.


2

Muito obrigado pelas outras respostas, com base nelas, foi o que eu usei para o prermarquivo do meu pacote Debian :

#!/bin/sh
set -e

deb_package='package-name'
python_package='package_name'

if which pyclean >/dev/null 2>&1; then
    py3clean -p $deb_package
else
    dpkg -L $deb_package | grep ${python_package}$ | while read file
    do
        find ${file} -type d -name __pycache__ -exec rm -r {} \+
    done
fi

0

Por que não usar apenas rm -rf __pycache__? Execute git add -Adepois para removê-los do seu repositório e adicionar __pycache__/ao seu arquivo .gitignore.


1
Ele não está fazendo isso manualmente. Ele está tentando adicioná-lo a um script usado em um pacote Debian. Um pacote debian não é usado com o git, mas com o gerenciador de pacotes debian ou o instalador do apt.
Craig

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.