Test, ob man einen Namen benutzen dürfte

Code-Stücke können hier veröffentlicht werden.
Antworten
bremer
User
Beiträge: 109
Registriert: Sonntag 25. Mai 2008, 00:13

Code: Alles auswählen

import keyword
s = 'word'

def wordtest(s):
    notallowed = 0
    if keyword.iskeyword(s) == True:
        print('\'' + s + '\' is a keyword.')
        notallowed = 1
    else:
        print('\'' + s + '\' is no keyword.')

    if s in dir(__builtins__):
        print('\'' + s + '\' is a built-in function.')
        notallowed = 1
    else:
        print('\'' + s + '\' is not a built-in function.')

    try:
        exec('import ' + s)
        print('\'' + s + '\' is a module.')
        notallowed = 1
    except ImportError:
        print('\'' + s + '\' is no module.')
        
    print()
    if notallowed == 1:
        print('The use of \'' + s + '\' is discouraged.')
    else:
        print('The use of \'' + s + '\' is encouraged.')

wordtest(s)
Das kurze Skript soll mir sagen, ob es in Ordnung ist einen bestimmten Namen zu benutzen. Für "input", "str" oder "string" ist es das z. B. nicht.

Kommentare, Ergänzungen? Was könnte ich vergessen haben?
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

besser:

Code: Alles auswählen

import keyword
s = 'word'

def wordtest(s):
    notallowed = 0
    if keyword.iskeyword(s) == True:
        print('\'' + s + '\' is a keyword.')
        notallowed = 1
    else:
        print('\'' + s + '\' is no keyword.')

    if s in dir(__builtins__):
        print('\'' + s + '\' is a built-in function.')
        notallowed = 1
    else:
        print('\'' + s + '\' is not a built-in function.')

    try:
        exec('import ' + s)
        print('\'' + s + '\' is a module.')
        notallowed = 1
    except (SyntaxError,ImportError):
        print('\'' + s + '\' is no module.')
       
    print()
    if notallowed == 1:
        print('The use of \'' + s + '\' is discouraged.')
    else:
        print('The use of \'' + s + '\' is encouraged.')

wordtest(s)
sonst wirft es einen syntax-error, wenn man ein keyword verwendet^^

E:// ich seh grade, war noch ein fehler drin^^
BlackJack

Zahlen für Wahrheitswerte und explizites Testen auf ``== True`` oder ``== False`` sind unschön. Die "Backslasherei" ist auch nicht schön anzusehen. Man kann Zeichenketten auch in " einfassen und ' darin ganz normal verwenden.

Die Existenz von `__builtins__` ist ein Implementierungsdetail. Robuster ist es das `__builtin__`-Modul zu importieren.

Code: Alles auswählen

import __builtin__
import imp
import keyword


def wordtest(word):
    
    def import_test(w):
        try:
            imp.find_module(w)
            return True
        except (ImportError, SyntaxError):
            return False
    
    tests = [(keyword.iskeyword, 'keyword'),
             (dir(__builtin__).__contains__, 'built-in function'),
             (import_test, 'module or package')]
    
    discouraged = False
    for test_func, description in tests:
        tmp = test_func(word)
        print '%r is %s %s.' % (word, 'a' if tmp else 'not a', description)
        discouraged = discouraged or tmp
    
    print '\nThe use of %r is %s.' % (word,
                                      'discouraged' if discouraged
                                                    else 'encouraged')

def main():
    for word in ['foo', 'class', 'float', 'math']:
        wordtest(word)
        print '-' * 40
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Code: Alles auswählen

 (((1 == 1) == True) == True) == True

Code: Alles auswählen

if keyword.iskeyword(s) == True: 
Den Test, ob True == True ist musst du nicht selbst machen. Da kommt tatsächlich wieder "nur" True heraus, das du nach deine Art eigentlich nochmal Testen müsstest ;)

€dit:
Ich seh gerade: Blackjack kam mir zuvor, der Schüft!
Das kommt davon, nen Tab zu lange offen zu lassen...
Zuletzt geändert von audax am Montag 29. Dezember 2008, 07:58, insgesamt 1-mal geändert.
bremer
User
Beiträge: 109
Registriert: Sonntag 25. Mai 2008, 00:13

Ok.

Mein alter Code nochmal aufgefrischt:

Code: Alles auswählen

import keyword
s = 'dir'

def wordtest(s):
    notallowed = 0
    if keyword.iskeyword(s):
        print("'" + s + "' is a keyword.")
        notallowed = 1
    else:
        print("'" + s + "' is no keyword.")

    if s in dir(__builtins__):
        print("'" + s + "' is a built-in function.")
        notallowed = 1
    else:
        print("'" + s + "' is not a built-in function.")

    try:
        exec('import ' + s)
        print("'" + s + "' is a module.")
        notallowed = 1
    except (ImportError, SyntaxError):
        print("'" + s + "' is no module.")
        
    print()
    if notallowed:
        print("The use of '" + s + "' is discouraged.")
    else:
        print("The use of '" + s + "' is encouraged.")

wordtest(s)
@Blackjack: Das Imp-Modul ist da aber auch nicht notwendig, oder?
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Reicht nicht ein `eval(name)` und schauen, ob ein NameError geworfen wird? Falls nein, ist das keine Variable, die man benutzen kann. Alle anderen Fehler oder auch kein Fehler sagen, dass der Name nicht benutzt werden kann.

Stefan
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

sma hat geschrieben:Reicht nicht ein `eval(name)` und schauen, ob ein NameError geworfen wird? Falls nein, ist das keine Variable, die man benutzen kann. Alle anderen Fehler oder auch kein Fehler sagen, dass der Name nicht benutzt werden kann.

Stefan
Dann weiß man aber immer noch nicht, ob es ein Modul ist, da die Modulnamen ja nicht alle schon global definiert sind (in globals())...
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Nur, wenn das Modul schon importiert wurde. Es auf Verdacht zu importieren kann üble Nebenwirkungen haben, daher würde ich darauf verzichten. Das eval() berücksichtigt ja den aktuellen Zustand des Systems, ich finde, das reicht.

Stefan
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

dann könnte man auch

Code: Alles auswählen

try:
    m = __import__("word")
    del m
    print ("Modul!")
except ImportError:
    print ("kein modul")
schreiben...
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Und wenn in dem Modul dies steht?

Code: Alles auswählen

while True: pass
Du kannst nicht wissen, ob du aus dem "import" je wieder zurückkehren wirst.

Stefan
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Code: Alles auswählen

>>> try:
...     m = __import__("this")
...     del m
...     print ("Modul!")
... except ImportError:
...     print ("kein modul")
...
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Modul!
>>>
Könnte'ne Sicherheitslücke geben. Aber eigentlich is's im Endeffekt doch auch egal, ob man einen Namen verwendet den man auch importieren könnte o.o Man kann ja auch die meisten Modulnamen als Variablen benutzen ^__^ Aber vllt versteh ich die Aufgabe... also den Zweck des Ganzen nicht 100%!...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

bremer hat geschrieben:@Blackjack: Das Imp-Modul ist da aber auch nicht notwendig, oder?
Mit ``imp`` ist es aber wesentlich schöner, da dynamische Codeausführung via ``eval`` (trifft für ``exec`` genauso zu) hässlich ist. Schließlich will man das Modul nicht ausführen sondern nur schauen ob es importierbar ist.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Das Imp-Modul ist da aber auch nicht notwendig, oder?
imp ist ein Lowlevel Interface zum Import System. imp.find_module versucht, ein Modul zu finden und importiert es nicht, insofern hilft die Verwendung von imp bei der Vermeidung aller Probleme, die hier in Bezug auf den Import eines Modules schon angesprochen wurden.
bremer
User
Beiträge: 109
Registriert: Sonntag 25. Mai 2008, 00:13

BlackVivi hat geschrieben: Aber eigentlich is's im Endeffekt doch auch egal, ob man einen Namen verwendet den man auch importieren könnte o.o Man kann ja auch die meisten Modulnamen als Variablen benutzen ^__^ Aber vllt versteh ich die Aufgabe... also den Zweck des Ganzen nicht 100%!...
Klar kann man das tun. Ich möchte trotzdem meine "Variablen" nicht string, array oder time usw. nennen. Ich persönlich trenne das strikt.
Antworten