Bir python, komut satırı programı nasıl yapılır, yorumlayıcı DEĞİL rastgele şeyler otomatik tamamlama


100

Python yorumlayıcısında (unix üzerinde) python nesnelerinin otomatik tamamlamasının nasıl kurulacağının farkındayım.

  • Google, bunun nasıl yapılacağına dair açıklamalar için birçok isabet gösterir.
  • Ne yazık ki, yapmam gerekeni bulmanın zor olduğuna dair çok fazla referans var, bu biraz farklı.

Python ile yazılmış bir komut satırı programında rasgele öğelerin nasıl etkinleştirileceğini, sekme / otomatik tamamlamayı bilmem gerekiyor.

Benim özel kullanım durumum, e-posta göndermesi gereken bir komut satırı python programıdır. Kullanıcı bir kısmını yazdığında (ve isteğe bağlı olarak SEKME tuşuna bastığında) e-posta adreslerini otomatik tamamlayabilmek istiyorum (adresler diskte var).

Windows veya mac üzerinde çalışmasına ihtiyacım yok, sadece linux.


Bu blog , .pythonrc dosyasını yapılandırarak hile yapmalıdır.
LF00

Yanıtlar:


65

Python'un readlinebağlamalarını kullanın . Örneğin,

import readline

def completer(text, state):
    options = [i for i in commands if i.startswith(text)]
    if state < len(options):
        return options[state]
    else:
        return None

readline.parse_and_bind("tab: complete")
readline.set_completer(completer)

Resmi modül belgeleri çok daha ayrıntılı değildir, daha fazla bilgi için okuma satırı belgelerine bakın .


1
eğer komut satırınızı cmd modülüyle yazarsanız, bunu yapmanın daha iyi yolları olduğunu unutmayın.
Florian Bösch

60

Cmd belgelerini takip edin ve iyi olacaksınız

import cmd

addresses = [
    'here@blubb.com',
    'foo@bar.com',
    'whatever@wherever.org',
]

class MyCmd(cmd.Cmd):
    def do_send(self, line):
        pass

    def complete_send(self, text, line, start_index, end_index):
        if text:
            return [
                address for address in addresses
                if address.startswith(text)
            ]
        else:
            return addresses


if __name__ == '__main__':
    my_cmd = MyCmd()
    my_cmd.cmdloop()

Sekme için çıktı -> sekme -> gönder -> sekme -> sekme -> f -> sekmesi

(Cmd)
help  send
(Cmd) send
foo@bar.com            here@blubb.com         whatever@wherever.org
(Cmd) send foo@bar.com
(Cmd)

Readline'ın çıktısını nasıl sütunlaştırdığını kontrol etmenin bir yolu var mı? Diyelim ki, her öğe arasında iki boşluk bırakarak sütun haline gelmesini istiyorum.
Fnord

Bu kodu çalıştırdığımda, sekmeler basitçe komut satırına yazdırılıyor. Aslında bu, cmd veya düz okuma satırı kullanmamdan bağımsız olarak doğrudur.
Hack Saw

38

Sorunuzda "yorumlayıcı DEĞİL" dediğinize göre, sanırım python okuma satırı ve benzerlerini içeren cevaplar istemiyorsunuz. ( Düzenleme : Geriye dönüp bakıldığında, durum böyle değil. Ho hum. Bence bu bilgi yine de ilginç, bu yüzden burada bırakacağım. )

Peşinde olabileceğini düşünüyorum bu .

Bu, bash'ın kendi sekme tamamlamasını genişleterek rastgele komutlara kabuk düzeyinde tamamlama eklemekle ilgilidir.

Özetle, olası tamamlamaları oluşturacak, onu kaydedecek /etc/bash_completion.d/ve komutla kaydettirecek bir kabuk işlevi içeren bir dosya oluşturacaksınız complete. İşte bağlantılı sayfadan bir pasaj:

_foo() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="--help --verbose --version"

    if [[ ${cur} == -* ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
}
complete -F _foo foo

Bu durumda, yazım foo --[TAB]size değişkendeki değerleri verecektir opts, yani --help, --verboseve --version. Amaçlarınız için, esasen yerleştirilen değerleri özelleştirmek isteyeceksiniz.opts .

Bağlantılı sayfadaki örneğe bir göz atın, hepsi oldukça basit.


11
Aslında buraya bunun için geldim
user1767754

Teşekkürler, tam olarak aradığım buydu!
Teekeks

30

Kimsenin argcomplete'den bahsetmemesine şaşırdım, işte dokümanlardan bir örnek:

from argcomplete.completers import ChoicesCompleter

parser.add_argument("--protocol", choices=('http', 'https', 'ssh', 'rsync', 'wss'))
parser.add_argument("--proto").completer=ChoicesCompleter(('http', 'https', 'ssh', 'rsync', 'wss'))

Eski bir gönderi, belki argcomplete o zamanlar mevcut değildi? Yine de bahsettiğiniz için teşekkürler, sanırım projemin tam olarak ihtiyacı olan şey bu!
FrustratedWithFormsDesigner

Argparse ile kombinasyon halinde de çok güzel !
AstroFloyd

14

Burada ephemient tarafından sağlanan kodun tam çalışan bir sürümü var (teşekkür ederim).

import readline

addrs = ['angela@domain.com', 'michael@domain.com', 'david@test.com']

def completer(text, state):
    options = [x for x in addrs if x.startswith(text)]
    try:
        return options[state]
    except IndexError:
        return None

readline.set_completer(completer)
readline.parse_and_bind("tab: complete")

while 1:
    a = raw_input("> ")
    print "You entered", a

10
# ~/.pythonrc
import rlcompleter, readline
readline.parse_and_bind('tab:complete')

# ~/.bashrc
export PYTHONSTARTUP=~/.pythonrc

1
Mac os için, değiştirmek readline.parse_and_bind('tab:complete') ilereadline.parse_and_bind ("bind ^I rl_complete")
Mani

Bu harika. Benim için çalıştı. Paylaşım için teşekkürler.
Ajay Ahuja

@Mani Uzun zamandır buna sıkıştım. Çok teşekkür ederim
AnaS Kayed

5

Python'da etkileşimli komut satırı uygulamaları oluşturmak için bir kitaplık olan Python Komut İstemi Araç Seti'ni kullanmayı deneyebilirsiniz .

Kitaplık, etkileşimli otomatik tamamlama işlevselliği eklemeyi kolaylaştırarak, kullanıcının Tabmevcut seçenekler arasında görsel olarak geçiş yapmak için anahtarı kullanmasına olanak tanır . Kitaplık çapraz platformdur (Linux, OS X, FreeBSD, OpenBSD, Windows). Misal:

pgcli - Python Komut İstemi Araç Seti

(Resim kaynağı: pcgli )


1

Gönderilen cevaplar iyi çalışıyor, ancak işyerinde yazdığım bir otomatik tamamlama kitaplığını açtım. Üretimde bir süredir kullanıyoruz ve hızlı, sağlam ve kullanımı kolay. Hatta bir demo moduna sahiptir, böylece kelimeleri yazarken ne alacağınızı hızlı bir şekilde test edebilirsiniz.

Yüklemek için şunu çalıştırın: pip install fast-autocomplete

İşte bir örnek:

>>> from fast_autocomplete import AutoComplete
>>> words = {'book': {}, 'burrito': {}, 'pizza': {}, 'pasta':{}}
>>> autocomplete = AutoComplete(words=words)
>>> autocomplete.search(word='b', max_cost=3, size=3)
[['book'], ['burrito']]
>>> autocomplete.search(word='bu', max_cost=3, size=3)
[['burrito']]
>>> autocomplete.search(word='barrito', max_cost=3, size=3)  # mis-spelling
[['burrito']]

Ödeme: https://github.com/wearefair/fast-autocomplete Kaynak kodu için .

Ve işte nasıl çalıştığına dair bir açıklama: http://zepworks.com/posts/you-autocomplete-me/

Yanlış yazımlar ve isteğe bağlı olarak kelimenin ağırlığına göre sıralama ile ilgilenir. (diyelim ki burritobundan daha önemlidir book, o zaman burritodaha yüksek bir "sayım" verirsiniz bookve sonuçlarda daha önce görünecektir .

Kelimeler bir sözlüktür ve her kelimenin bir bağlamı olabilir. Örneğin "sayma", kelimenin nasıl görüntüleneceği, kelimenin etrafında başka bir bağlam vb. Bu örnekte kelimelerin herhangi bir bağlamı yoktu.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.