පයිතන්හි ස්විච් ප්‍රකාශය සඳහා ආදේශන?


1718

ආදාන දර්ශකයක වටිනාකම මත පදනම්ව විවිධ ස්ථාවර අගයන් ලබා දෙන ශ්‍රිතයක් පයිතන් හි ලිවීමට මට අවශ්‍යය.

වෙනත් භාෂාවලින් මම ප්‍රකාශයක් switchහෝ caseප්‍රකාශයක් භාවිතා කරමි , නමුත් පයිතන්ට switchප්‍රකාශයක් ඇති බවක් නොපෙනේ . මෙම තත්වය තුළ නිර්දේශිත පයිතන් විසඳුම් මොනවාද?


77
අදාළ PEP, ගයිඩෝ විසින්ම රචනා කරන ලද්දකි: PEP 3103
chb

28
Pchb එම PEP හි, ගයිඩෝ / elif දාමයන් ද සම්භාව්‍ය දෝෂ ප්‍රභවයක් බව සඳහන් නොකරයි. එය ඉතා බිඳෙන සුළු ඉදිකිරීමකි.
බ ru ස්

15
මෙහි ඇති සියලුම විසඳුම් මඟ හැරීම යනු අනුපිටපත් අගයන් හඳුනා ගැනීමයි . අසාර්ථක-වේගවත් මූලධර්මයක් ලෙස, මෙය කාර්ය සාධනයට වඩා වැදගත් අලාභයක් විය හැකිය.
බොබ් ස්ටයින්

6
switchආදාන දර්ශකයක වටිනාකම මත පදනම්ව වෙනස් ස්ථාවර අගයන් ලබා දෙන දෙයකට වඩා ඇත්ත වශයෙන්ම “බහුකාර්ය” වේ. විවිධ කේත කැබලි ක්‍රියාත්මක කිරීමට එය ඉඩ දෙයි. එය ඇත්ත වශයෙන්ම වටිනාකමක් ආපසු ලබා දීමට පවා අවශ්ය නොවේ. මෙහි ඇති සමහර පිළිතුරු සාමාන්‍ය switchප්‍රකාශයක් සඳහා හොඳ ආදේශකයක්ද , නැතිනම් සාමාන්‍ය කේත කොටස් ක්‍රියාත්මක කිරීමට හැකියාවක් නොමැති අගයන් ආපසු ලබා දීම සඳහාද යන්න මට සිතේ .
sancho.s ReinstateMonicaCellio

3
@ MalikA.Rumi Fragile ඉදිකිරීම, ටික වේලාවකින් බිඳෙනසුලු ඉදිකිරීමක් වන අතර, ඔබ එය භාවිතා කිරීමට උත්සාහ කරන්නේ නම් ... in ... කරන්නේ කුමක්ද? ලූප සඳහා භාවිතා කිරීම සඳහා ඔබ ක්‍රමලේඛකයින් දුර්වල ලෙස හැඳින්වීමට යන්නේද? ලූප සියල්ලම ඇත්ත වශයෙන්ම අවශ්‍ය වේ. නමුත් ලූප සඳහා පැහැදිලි අභිප්‍රාය පෙන්වන අතර, අර්ථ විරහිත බොයිලේරු පුවරුව සුරකින්න සහ ප්‍රබල වියුක්තයන් නිර්මාණය කිරීමට අවස්ථාව ලබා දෙන්න.
බ ru ස්

Answers:


1499

ඔබට ශබ්ද කෝෂයක් භාවිතා කළ හැකිය:

def f(x):
    return {
        'a': 1,
        'b': 2,
    }[x]

100
X සොයාගත නොහැකි නම් කුමක් සිදුවේද?
නික්

46
icknick: ඔබට පෙරනිමිති භාවිතා කළ හැකිය
එලී බෙන්ඩර්ස්කි

386
කාර්යසාධනය ගැටළුවක් නම්, ශ්‍රිතයෙන් පිටත නියෝගය තැබීමට මම නිර්දේශ කරමි, එබැවින් එය සෑම ක්‍රියාකාරී ඇමතුමකදීම නැවත ගොඩනඟන්නේ නැත
ක්ලෝඩියු

56
Li එලිබෙන්ඩර්ස්කි, මෙම අවස්ථාවෙහිදී getභාවිතා කිරීමට වඩා ක්‍රමවේදය භාවිතා කිරීම සාමාන්‍ය දෙයක් වනු ඇත collections.defaultdict.
මයික් ග්‍රැහැම්

27
Ick නික්, ව්‍යතිරේකයක් විසි }.get(x, default)කරයි a පෙරනිමියක් තිබිය යුතු නම් ඒ වෙනුවට කරන්න . (සටහන: ඔබ පෙරනිමිය ස්විච් ප්‍රකාශයකින් ඉවත් කළහොත් සිදුවන දෙයට වඩා මෙය ඉතා හොඳය!)
මයික් ග්‍රැහැම්

1381

ඔබට පෙරනිමි අවශ්‍ය නම් ඔබට ශබ්ද කෝෂ get(key[, default])ක්‍රමය භාවිතා කළ හැකිය :

def f(x):
    return {
        'a': 1,
        'b': 2
    }.get(x, 9)    # 9 is default if x not found

12
'A' සහ 'b' 1 හා 'c' සහ 'd' ගැලපෙන්නේ නම් කුමක් කළ යුතුද?
ජෝන් මී

14
@ ජේඑම්: හොඳයි, පැහැදිලිවම ශබ්ද කෝෂ බැලීම් වැටීම් වලට සහාය නොදක්වයි. ඔබට ද්විත්ව ශබ්ද කෝෂයක් බැලීමට හැකිය. දෙවන ශබ්ද කෝෂයේ අඩංගු වන පිළිතුරු 1 ට 'සී' සහ 'ඩී' ලක්ෂ්‍යය පිළිතුරු 2 ට යොමු වේ.
නික්

3
පෙරනිමි අගයක් ලබා දීමට මෙය වඩා හොඳය
HaTiMSuM

මෙම ප්‍රවේශය සමඟ ගැටළුවක් ඇත, පළමුව ඔබ f අමතන සෑම අවස්ථාවකම ඔබ නැවතත් දෙවන වරට ආ ict ාව නිර්මාණය කිරීමට යන්නේ ඔබට වඩාත් සංකීර්ණ වටිනාකමක් ඇත්නම් ඔබට ව්‍යතිරේකයක් ලබා ගත හැකිය. x යනු ටුපල් එකක් නම් අපට මේ වගේ දෙයක් කිරීමට අවශ්‍ය නම් x = ('a') def f (x): ආපසු {'a': x [0], 'b': x [1]} .get ( x [0], 9) මෙය දර්ශක දෝෂය ඉහළ නංවනු ඇත
ඉඩාන් හයිම් ෂාලොම්

2
D අයිඩාන්: ප්‍රශ්නය වූයේ ස්විචය අනුකරණය කිරීමයි. අමුතු අගයන් දැමීමට උත්සාහ කළහොත් මට මෙම කේතය බිඳ දැමිය හැකි බව මට විශ්වාසයි. ඔව්, එය ප්‍රතිනිර්මාණය කරනු ඇත, නමුත් එය නිවැරදි කිරීම සරල ය.
නික්

400

මම හැම විටම කැමතියි මේ ආකාරයට එය කිරීමට

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}[value](x)

මෙතැන් සිට


16
පෙරනිමිය හැසිරවීම සඳහා get () සමඟ ඒකාබද්ධ කිරීම මගේ හොඳම තේරීමයි
drAlberT

27
මෙම අවස්ථාවේ දී ලැම්බඩා භාවිතා කිරීම හොඳ අදහසක් නොවනු ඇත, මන්ද ශබ්ද කෝෂය ගොඩනඟන සෑම අවස්ථාවකම ලැම්බඩා සැබවින්ම හැඳින්වේ.
ආශර්

14
කනගාටුවට කරුණ නම් මෙය ළඟම මිනිසුන් ලබා ගැනීමයි. භාවිතා කරන ක්‍රම .get()(වර්තමාන ඉහළම පිළිතුරු මෙන්) යැවීමට පෙර සියලු හැකියාවන් උනන්දුවෙන් ඇගයීමට ලක් කළ යුතු අතර, එම නිසා (ඉතා පමණක් නොව) අතිශයින්ම අකාර්යක්ෂම වන අතර අතුරු ආබාධ ඇතිවිය නොහැක. මෙම පිළිතුර එම ගැටළුව වටා ඇති නමුත් එය වඩාත් වාචික ය. මම භාවිතා කරන්නේ / elif / else නම්, ඒවා පවා 'නඩුව' ලෙස ලිවීමට තරම් කාලයක් ගතවේ.
ninjagecko

14
මෙය එක් එක් ප්‍රති results ල පමණක් ලබා දුන්නද, සෑම අවස්ථාවකම සෑම කාර්යයක්ම / ලැම්බඩාස් ඇගයීමට ලක් නොකරන්නේද?
slf

23
lslf නැත, පාලක ප්‍රවාහය එම කේත කැබැල්ලට ළඟා වූ විට, එය ශ්‍රිත 3 ක් (ලැම්බඩා 3 භාවිතා කිරීම හරහා) ගොඩනඟා පසුව එම ශ්‍රිත 3 සමඟ අගයන් ලෙස ශබ්දකෝෂයක් ගොඩනගනු ඇත, නමුත් ඒවා ගණනය නොකෙරේ ( ඇගයීම තරමක් අපැහැදිලි ය එම සන්දර්භය) මුලදී. එවිට ශබ්ද කෝෂය සුචිගත [value]කරනු ලැබේ, එමඟින් ශ්‍රිත 3 න් එකක් පමණක් ලැබෙනු ඇත ( valueයතුරු 3 න් එකක් යැයි උපකල්පනය කරන්න). එම අවස්ථාවේදී ශ්‍රිතය කැඳවා නැත. ඉන්පසු (x)නැවත ලබා දුන් ශ්‍රිතය xතර්කයක් ලෙස අමතන්න (ප්‍රති result ලය යන්නේ result). අනෙක් කාර්යයන් 2 කැඳවනු නොලැබේ.
blubberdiblub

360

ශබ්ද කෝෂ ක්‍රමවලට අමතරව (මම ඇත්තටම කැමති, BTW), ඔබට ද if- elif- elseලබා ගැනීමට භාවිතා කළ හැකියswitch / case/ default: ක්රියාකාරිත්වය

if x == 'a':
    # Do the thing
elif x == 'b':
    # Do the other thing
if x in 'bc':
    # Fall-through by not using elif, but now the default case includes case 'a'!
elif x in 'xyz':
    # Do yet another thing
else:
    # Do the default

මෙය ඇත්ත වශයෙන්ම මාරුවීමට / නඩුවට සමාන නොවේ - breakප්‍රකාශය අතහැර දැමීම තරම් පහසුවෙන් ඔබට වැටිය නොහැක , නමුත් ඔබට වඩාත් සංකීර්ණ පරීක්ෂණයක් කළ හැකිය. එහි හැඩතල ගැන්වීම කැදැලි මාලාවකට වඩා හොඳයි if, ක්‍රියාකාරීව වුවද එය එයට සමීප වේ.


53
මම මේකට ඇත්තෙන්ම කැමතියි, එය ස්ථාවර භාෂා නිර්මාණයක් භාවිතා කරන අතර ගැලපෙන නඩුවක් සොයාගත නොහැකි නම් යතුරු දෝෂයක් විසි නොකරයි
මාටිග්ලූබිට්ස්

7
මම ශබ්ද කෝෂය / getමාර්ගය ගැන සිතුවෙමි , නමුත් සම්මත ක්‍රමය වඩාත් කියවිය හැකිය.
මාටින් තෝමා

2
omeSomeuser නමුත් ඔවුන්ට "අතිච්ඡාදනය" කළ හැකි වීම ලක්ෂණයකි. ගැලපීම් සිදුවිය යුතු ප්‍රමුඛතාවය ඇණවුම බව ඔබ සහතික කර ගන්න. නැවත නැවත x සඳහා: x = the.other.thingපෙර කරන්න. සාමාන්‍යයෙන්, ඔබට තේරුම් ගැනීමට පහසු වන පරිදි තනි, බහු එලිෆ් සහ වෙනත් එකක් තිබේ නම්.
මැතිව් ෂින්කල්

7
හොඳයි, “එලිෆ් භාවිතා නොකිරීමෙන් වැටීම” ටිකක් අවුල් සහගතයි. මේ ගැන කුමක් කිව හැකිද: "වැටීම" ගැන අමතක කර එය දෙකක් ලෙස පිළිගන්න if/elif/else?
ඇලෝයිස් මහඩාල්

7
ද වටිනා වැනි දේවල් භාවිතා කරන විට සඳහන් වූ, x in 'bc'මතක තබා ගන්න බව, "" in "bc"True.
ලොහ්මාර් අෂාර්

185

ස්විචය / නඩුව සඳහා මගේ ප්‍රියතම පයිතන් වට්ටෝරුව:

choices = {'a': 1, 'b': 2}
result = choices.get(key, 'default')

සරල අවස්ථා සඳහා කෙටි හා සරල.

සී කේතයේ පේළි 11+ සමඟ සසඳන්න:

// C Language version of a simple 'switch/case'.
switch( key ) 
{
    case 'a' :
        result = 1;
        break;
    case 'b' :
        result = 2;
        break;
    default :
        result = -1;
}

ටුපල් භාවිතා කිරීමෙන් ඔබට බහු විචල්‍යයන් පවා පැවරිය හැකිය:

choices = {'a': (1, 2, 3), 'b': (4, 5, 6)}
(result1, result2, result3) = choices.get(key, ('default1', 'default2', 'default3'))

16
මෙය පිළිගත් ඒවාට වඩා ශක්තිමත් පිළිතුරක් බව මට පෙනේ.
සහතිකය

3
සමහර පරිශීලකයා: C සඳහා ප්‍රතිලාභ අගය සියලු අවස්ථා සඳහා එකම වර්ගයේ විය යුතුය. පයිතන් එසේ නොවේ. යමෙකුට එවැනි භාවිතයක් අවශ්‍ය තත්වයක් ඇති වුවහොත් පයිතන්ගේ මෙම නම්‍යශීලී බව ඉස්මතු කිරීමට මට අවශ්‍ය විය.
ChaimG

3
සමහර පරිශීලකයා: පුද්ගලිකව, මට read} .get (,) කියවිය හැකි බව පෙනේ. පයිතන් ආරම්භකයින් සඳහා අමතර කියවීමේ හැකියාව සඳහා ඔබට භාවිතා කිරීමට අවශ්‍ය විය හැකිය default = -1; result = choices.get(key, default).
ChaimG

4
c ++ 1 පේළියක් සමඟ සසඳන්නresult=key=='a'?1:key==b?2:-1
Jasen

4
As ජේසන්ට ඔබට පයිතන්හි එක් පේළියකින් ද එය කළ හැකි යැයි තර්ක කළ හැකිය : result = 1 if key == 'a' else (2 if key == 'b' else 'default'). නමුත් එක් ලයිනර් කියවිය හැකිද?
ChaimG

101
class switch(object):
    value = None
    def __new__(class_, value):
        class_.value = value
        return True

def case(*args):
    return any((arg == switch.value for arg in args))

භාවිතය:

while switch(n):
    if case(0):
        print "You typed zero."
        break
    if case(1, 4, 9):
        print "n is a perfect square."
        break
    if case(2):
        print "n is an even number."
    if case(2, 3, 5, 7):
        print "n is a prime number."
        break
    if case(6, 8):
        print "n is an even number."
        break
    print "Only single-digit numbers are allowed."
    break

පරීක්ෂණ:

n = 2
#Result:
#n is an even number.
#n is a prime number.
n = 11
#Result:
#Only single-digit numbers are allowed.

64
මෙය තර්ජනාත්මක ආරක්ෂිත නොවේ. එකවර ස්විචයන් කිහිපයකට පහර දුන්නොත් සියලුම ස්විචයන් අවසාන ස්විචයේ අගය ගනී.
francescortiz

48
@Franscortiz යන්නෙන් අදහස් කරන්නේ නූල් ආරක්ෂිතයි, නමුත් එය තර්ජනාත්මක ආරක්ෂිත නොවේ. එය විචල්යයන්ගේ අගයන්ට තර්ජනය කරයි!
Zizouz212

7
නූල්-දේශීය ආචයනය භාවිතා කිරීමෙන් නූල් ආරක්ෂණ ගැටළුව විසඳා ගත හැකිය . එසේත් නැතිනම් සිද්ධියක් සැසඳීම සඳහා එම අවස්ථාව භාවිතා කිරීමෙන් එය සම්පූර්ණයෙන්ම වළක්වා ගත හැකිය.
blubberdiblub

6
lblubberdiblub නමුත් සම්මත ifප්‍රකාශයක් භාවිතා කිරීම වඩා කාර්යක්ෂම නොවේද?
wizzwizz4

9
බහු කාර්යයන් සඳහා භාවිතා කරන්නේ නම් මෙයද ආරක්ෂිත නොවේ. ලබා දී ඇති උදාහරණයේ දී, case(2)ස්විචය () භාවිතා කරන වෙනත් ශ්‍රිතයක් බ්ලොක් ලෙස හැඳින්වුවහොත් case(2, 3, 5, 7), ඊළඟ නඩුව ක්‍රියාත්මක කිරීම සඳහා සෙවීම සඳහා යනාදිය කරන විට , එය භාවිතා කරනුයේ අනෙක් ශ්‍රිතය මඟින් සකසා ඇති ස්විච් අගය වත්මන් ස්විච් ප්‍රකාශයෙන් සැකසූ එකක් නොවේ. .
user9876

52

මගේ ප්‍රියතම එක ඇත්තෙන්ම හොඳ වට්ටෝරුවකි . ඔබ ඇත්තටම එයට කැමති වනු ඇත. තථ්‍ය ස්විච් සිද්ධි ප්‍රකාශයන්ට, විශේෂයෙන් විශේෂාංග වලට මා දුටු ආසන්නතම අවස්ථාව එයයි.

class switch(object):
    def __init__(self, value):
        self.value = value
        self.fall = False

    def __iter__(self):
        """Return the match method once, then stop"""
        yield self.match
        raise StopIteration

    def match(self, *args):
        """Indicate whether or not to enter a case suite"""
        if self.fall or not args:
            return True
        elif self.value in args: # changed for v1.5, see below
            self.fall = True
            return True
        else:
            return False

මෙන්න උදාහරණයක්:

# The following example is pretty much the exact use-case of a dictionary,
# but is included for its simplicity. Note that you can include statements
# in each suite.
v = 'ten'
for case in switch(v):
    if case('one'):
        print 1
        break
    if case('two'):
        print 2
        break
    if case('ten'):
        print 10
        break
    if case('eleven'):
        print 11
        break
    if case(): # default, could also just omit condition or 'if True'
        print "something else!"
        # No need to break here, it'll stop anyway

# break is used here to look as much like the real thing as possible, but
# elif is generally just as good and more concise.

# Empty suites are considered syntax errors, so intentional fall-throughs
# should contain 'pass'
c = 'z'
for case in switch(c):
    if case('a'): pass # only necessary if the rest of the suite is empty
    if case('b'): pass
    # ...
    if case('y'): pass
    if case('z'):
        print "c is lowercase!"
        break
    if case('A'): pass
    # ...
    if case('Z'):
        print "c is uppercase!"
        break
    if case(): # default
        print "I dunno what c was!"

# As suggested by Pierre Quentel, you can even expand upon the
# functionality of the classic 'case' statement by matching multiple
# cases in a single shot. This greatly benefits operations such as the
# uppercase/lowercase example above:
import string
c = 'A'
for case in switch(c):
    if case(*string.lowercase): # note the * for unpacking as arguments
        print "c is lowercase!"
        break
    if case(*string.uppercase):
        print "c is uppercase!"
        break
    if case('!', '?', '.'): # normal argument passing style also applies
        print "c is a sentence terminator!"
        break
    if case(): # default
        print "I dunno what c was!"

3
මම ආදේශ වනු ඇත for case in switch()සමගwith switch() as case එය එක් වරක් පමණක් ක්රියාත්මක කිරීමට ගේ අවශ්ය නිසා, වැඩි තේරුමක්.
ස්කී

4
K ස්කිර්මැන්ටාස්: කෙසේ වෙතත් withඑයට ඉඩ නොදෙන සටහන break, එබැවින් පහත වැටීමේ විකල්පය ඉවත් කරනු ලැබේ.
ජොනස් ෂෝෆර්

5
මෙය මා විසින්ම තීරණය කිරීමට වැඩි උත්සාහයක් නොගැනීම ගැන සමාව ඉල්ලන්න: ඉහත සමාන පිළිතුරක් නූල් ආරක්ෂිත නොවේ. මේක?
ඩේවිඩ් විනීකි

1
Av ඩේවිඩ් විනෙක්කි ඉහත සඳහන් කර නැති කේත සංරචක (සහ සමහර විට සක්‍රීය රාජ්‍යයේ ප්‍රකාශන අයිතිය) නූල් ආරක්ෂිත බව පෙනේ.
ජේසන්

මෙහි තවත් අනුවාදයක් වැනි දෙයක් විය if c in set(range(0,9)): print "digit" elif c in set(map(chr, range(ord('a'), ord('z')))): print "lowercase"හැකිද?
mpag

51
class Switch:
    def __init__(self, value):
        self.value = value

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        return False # Allows a traceback to occur

    def __call__(self, *values):
        return self.value in values


from datetime import datetime

with Switch(datetime.today().weekday()) as case:
    if case(0):
        # Basic usage of switch
        print("I hate mondays so much.")
        # Note there is no break needed here
    elif case(1,2):
        # This switch also supports multiple conditions (in one line)
        print("When is the weekend going to be here?")
    elif case(3,4):
        print("The weekend is near.")
    else:
        # Default would occur here
        print("Let's go have fun!") # Didn't use case for example purposes

9
සන්දර්භය කළමනාකරුවන් භාවිතා කිරීම හොඳ නිර්මාණාත්මක විසඳුමකි. මෙම ලිපියට යම්කිසි හොඳ සන්දර්භයක් ලබා දීම සඳහා සන්දර්භය කළමණාකරුවන් පිළිබඳ යම් තොරතුරක් සඳහා සබැඳියක් එකතු කිරීමට මම නිර්දේශ කරමි;)
Will

2
/ එලිෆ් දම්වැල් වැඩිපුර තිබේ නම් මම කැමති නැත, නමුත් මෙය පයිතන්ගේ දැනට පවතින වාක්‍ය ඛණ්ඩය භාවිතා කර මා දුටු සියලු විසඳුම් අතරින් වඩාත්ම නිර්මාණාත්මක හා වඩාත්ම ප්‍රායෝගික වේ.
itsbruce

2
මේක ඇත්තටම හොඳයි. යෝජිත එක් වැඩිදියුණු කිරීමක් නම් value, ස්විච් පන්තියට (පොදු) දේපලක් එක් කිරීම මඟින් ඔබට case.valueප්‍රකාශය තුළ සඳහන් කළ හැකිය .
පීටර්

48

Twisted Python කේතයෙන් මම ඉගෙන ගත් රටාවක් තිබේ.

class SMTP:
    def lookupMethod(self, command):
        return getattr(self, 'do_' + command.upper(), None)
    def do_HELO(self, rest):
        return 'Howdy ' + rest
    def do_QUIT(self, rest):
        return 'Bye'

SMTP().lookupMethod('HELO')('foo.bar.com') # => 'Howdy foo.bar.com'
SMTP().lookupMethod('QUIT')('') # => 'Bye'

ඔබට ටෝකනයකින් යැවීමට සහ දිගු කේත කැබැල්ලක් ක්‍රියාත්මක කිරීමට අවශ්‍ය ඕනෑම වේලාවක එය භාවිතා කළ හැකිය. රාජ්ය යන්ත්රයක ඔබට state_ක්රම තිබේ, සහ යැවීම self.state. මූලික පන්තියෙන් උරුම වීමෙන් සහ ඔබේම do_ක්‍රම නිර්වචනය කිරීමෙන් මෙම ස්විචය පිරිසිදු ලෙස දිගු කළ හැකිය . බොහෝ විට ඔබට do_මූලික පන්තියේ ක්‍රම පවා නොතිබෙනු ඇත .

සංස්කරණය කරන්න: එය හරියටම භාවිතා කරන්නේ කෙසේද?

SMTP නම් ඔබට කම්බියෙන් ලැබෙනු HELOඇත. අදාළ කේතය (සිට twisted/mail/smtp.py, අපගේ නඩුව සඳහා වෙනස් කරන ලදි) මේ වගේ ය

class SMTP:
    # ...

    def do_UNKNOWN(self, rest):
        raise NotImplementedError, 'received unknown command'

    def state_COMMAND(self, line):
        line = line.strip()
        parts = line.split(None, 1)
        if parts:
            method = self.lookupMethod(parts[0]) or self.do_UNKNOWN
            if len(parts) == 2:
                return method(parts[1])
            else:
                return method('')
        else:
            raise SyntaxError, 'bad syntax'

SMTP().state_COMMAND('   HELO   foo.bar.com  ') # => Howdy foo.bar.com

ඔබට ලැබෙනු ඇත ' HELO foo.bar.com '(නැතහොත් ඔබට ලැබෙනු ඇත 'QUIT'හෝ 'RCPT TO: foo'). මෙය ටෝකනය කර partsඇත ['HELO', 'foo.bar.com']. සත්‍ය ක්‍රමවේදය බැලීමේ නම ලබාගෙන ඇත parts[0].

(මුල් ක්‍රමය ද හැඳින්වේ state_COMMAND, මන්ද එය රාජ්‍ය යන්ත්‍රයක් ක්‍රියාත්මක කිරීම සඳහා එකම රටාව භාවිතා කරන බැවිනි, එනම් getattr(self, 'state_' + self.mode))


4
ක්‍රමවේදයන් කෙලින්ම ඇමතීමෙන් මෙම රටාවෙන් ලැබෙන ප්‍රයෝජනය මා දකින්නේ නැත: SMTP (). Do_HELO ('foo.bar.com') හරි, බැලීමේ ක්‍රමයේ පොදු කේතයක් තිබිය හැකි නමුත්, එය ද නැවත ලිවිය හැකිය. උප පංතිය ඔබ අවිනිශ්චිතතාවයෙන් ලබා ගන්නා දේ මට නොපෙනේ.
ෂාක් මහතා

1
කල්තියා ඇමතිය යුතු ක්‍රමය කුමක්දැයි ඔබ නොදනී, එනම් 'හෙලෝ' පැමිණෙන්නේ විචල්‍යයකිනි. මම මුල් පෝස්ටයට භාවිත උදාහරණය එකතු කර ඇත

මම සරලව යෝජනා කරමි: eval ('SMTP (). Do_' + command) ('foo.bar.com')
jforberg

8
eval? බරපතල ලෙස? ඇමතුමකට එක් ක්‍රමයක් ක්ෂණිකව ස්ථාපනය කරනවා වෙනුවට, අපට එක් වරක් ඉතා ඉක්මණින් ක්ෂණිකව ක්ෂණිකව ක්‍රියා කළ හැකි අතර එයට අභ්‍යන්තර තත්වයක් නොමැති නම් එය සියලු ඇමතුම් වලදී භාවිතා කළ හැකිය.
මහේෂ්

1
IMO මෙහි සැබෑ යතුර වන්නේ ක්‍රියාත්මක කිරීම සඳහා ශ්‍රිතයක් නියම කිරීම සඳහා getattr භාවිතා කර යැවීමයි. ක්‍රම මොඩියුලයක තිබුනේ නම්, ඔබට එය ලබා ගැනීම සඳහා getattr (ප්‍රාදේශීය (), func_name) කළ හැකිය. 'Do_' කොටස ආරක්ෂාව / දෝෂ සඳහා හොඳ බැවින් උපසර්ගය සහිත විනෝදය පමණක් හැඳින්විය හැකිය. SMTP විසින්ම lookupMethod ලෙස හැඳින්වේ. ඉතා මැනවින් පිටස්තරයා මේ කිසිවක් ගැන දන්නේ නැත. SMTP () කිරීම ඇත්තෙන්ම තේරුමක් නැත. බැලීමේ ක්‍රමය (නම) (දත්ත). විධානය සහ දත්ත එක් පේළියක ඇති අතර SMTP එය විග්‍රහ කරන බැවින් එය වඩාත් අර්ථවත් කරයි. අවසාන වශයෙන්, SMTP බොහෝ විට වෙනත් හවුල් තත්වයක් ඇති අතර එය පන්තියක් වීම සාධාරණීකරණය කරයි.
ෂෝන්ෆුමෝ

27

ඔබට වටිනාකමක් ලබා දීමට අවශ්‍ය නැති බව කියමු, නමුත් වස්තුවක් මත යමක් වෙනස් කරන ක්‍රම භාවිතා කිරීමට අවශ්‍යය. මෙහි දක්වා ඇති ප්‍රවේශය භාවිතා කිරීම:

result = {
  'a': obj.increment(x),
  'b': obj.decrement(x)
}.get(value, obj.default(x))

මෙහි සිදුවන්නේ පයිතන් ශබ්ද කෝෂයේ ඇති සියලුම ක්‍රම ඇගයීමයි. ඒ නිසා ඔබේ වටිනාකම 'a' පවා, වස්තුව නිලධාරිෙයකු වනු ඇත හා x මගින් අඩු වේ.

විසඳුමක්:

func, args = {
  'a' : (obj.increment, (x,)),
  'b' : (obj.decrement, (x,)),
}.get(value, (obj.default, (x,)))

result = func(*args)

එබැවින් ඔබට ශ්‍රිතයක් සහ එහි තර්ක අඩංගු ලැයිස්තුවක් ලැබේ. මේ ආකාරයෙන්, ශ්‍රිත දර්ශකය සහ තර්ක ලැයිස්තුව පමණක් ආපසු ලැබෙනු ඇත, ඇගයීමට ලක් නොකෙරේ . 'ප්‍රති result ලය' ඉන්පසු ආපසු එන ශ්‍රිත ඇමතුම ඇගයීමට ලක් කරයි.


24

මම මගේ ශත දෙක මෙතනට දාන්නම්. පයිතන්හි නඩුවක් / ස්විච් ප්‍රකාශයක් නොතිබීමට හේතුව පයිතන් 'යමක් කිරීමට ඇත්තේ එකම නිවැරදි ක්‍රමයයි' යන මූලධර්මය අනුගමනය කිරීමයි. එබැවින් පැහැදිලිවම ඔබට ස්විච් / කේස් ක්‍රියාකාරිත්වය ප්‍රතිනිර්මාණය කිරීමේ විවිධ ක්‍රම ඉදිරිපත් කළ හැකිය, නමුත් මෙය සාක්ෂාත් කර ගැනීමේ පයිතොනික් ක්‍රමය නම් / එලිෆ් ඉදිකිරීම් වේ. එනම්

if something:
    return "first thing"
elif somethingelse:
    return "second thing"
elif yetanotherthing:
    return "third thing"
else:
    return "default thing"

මට දැනුනේ PEP 8 මෙහි අනුමැතිය ලැබිය යුතු බවයි. පයිතන් පිළිබඳ සුන්දර දේවලින් එකක් වන්නේ එහි සරල බව සහ අලංකාරයයි. එය බොහෝ දුරට ව්‍යුත්පන්න වී ඇත්තේ PEP 8 හි සඳහන් කර ඇති මූලධර්මයන්ගෙන් වන අතර, “යමක් කිරීමට ඇත්තේ එකම නිවැරදි මාර්ගයයි”


7
ඉතින් පයිතන්ට ලූප සහ ලූප සඳහා ඇත්තේ ඇයි? For for loop එකකින් ඔබට කළ හැකි සෑම දෙයක්ම ඔබට ටික වේලාවක් ක්‍රියාත්මක කළ හැකිය.
බ ru ස්

1
සැබෑ. ආරම්භක ක්‍රමලේඛකයින් විසින් මාරුවීම / නඩුව බොහෝ විට අපයෝජනයට ලක් වේ. ඔවුන්ට සැබවින්ම අවශ්‍ය වන්නේ උපාය රටාවයි .
user228395

පයිතන් ප්‍රාර්ථනා කරන්නේ එය ක්ලෝජුර්
ටීඩබ්ලිව්ආර් කෝල්

1
WTWRCole මම හිතන්නේ නැහැ, පයිතන් මුලින්ම එය කළා. පයිතන් 1990 සිට සහ 2007 සිට ක්ලෝජුර් ය.
ටේලර්

යමක් කිරීමට ඇත්තේ එකම නිවැරදි මාර්ගයයි. පයිතන් 2.7 හෝ පයිතන් 3? Lol.
TWR කෝල්

17

"ඩික්ට් ස්විච්" අදහස මත පුළුල් කිරීම. ඔබගේ ස්විචය සඳහා පෙරනිමි අගයක් භාවිතා කිරීමට ඔබට අවශ්‍ය නම්:

def f(x):
    try:
        return {
            'a': 1,
            'b': 2,
        }[x]
    except KeyError:
        return 'default'

14
පෙරනිමියෙන් නියම කර ඇති පරිදි .get () භාවිතා කිරීම වඩාත් පැහැදිලි යැයි මම සිතමි. සුවිශේෂී අවස්ථාවන් සඳහා ව්‍යතිරේකයන් අතහැර යාමට මම කැමැත්තෙමි, එය අපැහැදිලි නොවී කේත පේළි තුනක් සහ ඉන්ඩෙන්ටේෂන් මට්ටමක් කපා දමයි.
ක්‍රිස් බී

10
මෙම වන සුවිශේෂී තත්ත්වයක්. එය ප්‍රයෝජනවත් දේ මත පදනම්ව දුර්ලභ අවස්ථාවක් විය හැකිය හෝ නොවිය හැකිය , නමුත් එය නියත වශයෙන්ම 'default'නීතියෙන් ව්‍යතිරේකයකි (ආපසු වැටෙන්න ) (මෙම නියෝගයෙන් යමක් ලබා ගන්න). සැලසුම අනුව, පයිතන් වැඩසටහන් තොප්පියක් වැටෙන විට ව්‍යතිරේක භාවිතා කරයි. එසේ පැවසීමෙන්, getකේතය තරමක් හොඳ කළ හැකිය.
මයික් ග්‍රැහැම්

17

කාර්යයන් ක්‍රියාත්මක කිරීමට විසඳුම:

result = {
    'case1':     foo1, 
    'case2':     foo2,
    'case3':     foo3,
    'default':   default,
}.get(option)()

එහිදී foo1 (), foo2 (), foo3 () සහ පෙරනිමි () යනු ශ්‍රිත වේ


1
ඔව්, උදාහරණයක් ලෙස ඔබේ විචල්‍ය විකල්පය නම් == "case2" ඔබේ ප්‍රති result ලය = foo2 ()
ඇලෙජැන්ඩ්‍රෝ ක්වින්ටනාර්


ඔව්, මට අරමුණ තේරෙනවා. එහෙත්, මාගේ කනස්සල්ල ඔබ පමණක් අවශ්ය නම් වේ foo2(), මෙම foo1(), foo3()සහ default()කාර්යයන් සියල්ල ද ක්රියාත්මක කිරීමට, යන අර්ථය දේ දීර්ඝ කාලයක් ගත විය හැකි වේ
බ්රයන් අන්ඩර්වුඩ්

1
ශබ්ද කෝෂය තුළ () මඟ හරින්න. භාවිතය get(option)(). ගැටළුව විසඳා ඇත.
timgeb

1
() භාවිතා කිරීම විශිෂ්ට විසඳුමක් වන අතර, එය පරීක්ෂා කිරීම සඳහා මම සාරාංශයක් ඉදිරිපත් කළෙමි gist.github.com/aquintanar/01e9920d8341c5c6252d507669758fe5
Alejandro Quintanar

16

ඔබට සංකීර්ණ සිද්ධි වාරණයක් තිබේ නම්, ශ්‍රිත ශබ්ද කෝෂ බැලීමේ වගුවක් භාවිතා කිරීම ගැන සලකා බැලිය හැකිය ...

ඔබේ නිදොස්කරණයට පිවිසීම සහ ශබ්දකෝෂය එක් එක් ශ්‍රිතය දෙස බලන ආකාරය බැලීම හොඳ අදහසක් වීමට පෙර ඔබ මෙය කර නොමැති නම්.

සටහන: කිසිවිටෙකත් නෑ "()" මෙම නඩුව තුළ / ශබ්ද කෝෂය බැලීම භාවිතා හෝ ශබ්ද කෝෂය / නඩුව වාරණ නිර්මාණය ලෙස එය ඔබගේ එක් එක් කාර්ය කියනු ඇත. මෙය මතක තබා ගන්න ඔබට අවශ්‍ය වන්නේ එක් එක් ශ්‍රිතය ඇමතීමට අවශ්‍ය වන්නේ එක් වරක් හැෂ් ස්ටයිල් බැලීමක් භාවිතා කරමිනි.

def first_case():
    print "first"

def second_case():
    print "second"

def third_case():
    print "third"

mycase = {
'first': first_case, #do not use ()
'second': second_case, #do not use ()
'third': third_case #do not use ()
}
myfunc = mycase['first']
myfunc()

මම ඔබේ විසඳුමට කැමතියි. නමුත්, මට යම් විචල්‍යයන් හෝ වස්තු සම්මත කිරීමට අවශ්‍ය නම් කුමක් කළ යුතුද?
ටෙඩෝ වර්බනෙක්

ක්රමය පරාමිතීන් අපේක්ෂා කරන්නේ නම් මෙය ක්රියා නොකරනු ඇත.
කුලසංගර්

16

මෙහි ඇති පිළිතුරු බොහොමයක් පැරණි ඒවා වන අතර විශේෂයෙන් පිළිගත් ඒවා බැවින් එය යාවත්කාලීන කිරීම වටී.

පළමුව, නිල පයිතන් නිති අසන ප්‍රශ්න මෙය ආවරණය elifකරන අතර සරල අවස්ථා සඳහා දාමය සහ dictවිශාල හෝ වඩා සංකීර්ණ අවස්ථා සඳහා දාමය නිර්දේශ කරයි . visit_සමහර අවස්ථා සඳහා ක්‍රම මාලාවක් (බොහෝ සේවාදායක රාමු භාවිතා කරන විලාසිතාවක්) ද එය යෝජනා කරයි :

def dispatch(self, value):
    method_name = 'visit_' + str(value)
    method = getattr(self, method_name)
    method()

නිතර අසනු ලබන ප්‍රශ්නවල PEP 275 ගැන සඳහන් වන අතර එය සී-ස්ටයිල් ස්විච් ප්‍රකාශ එකතු කිරීම පිළිබඳ නිල සහ එක් වරක් තීරණය ලබා ගැනීම සඳහා ලියා ඇත. නමුත් එම PEP සැබවින්ම පයිතන් 3 වෙත කල් දැමූ අතර එය නිල වශයෙන් ප්‍රතික්ෂේප කරනු ලැබුවේ වෙනම යෝජනාවක් වන PEP 3103 ලෙස පමණි . පිළිතුර ඇත්ත වශයෙන්ම නැත - නමුත් ඔබ හේතු හෝ ඉතිහාසය ගැන උනන්දුවක් දක්වන්නේ නම් PEPs දෙකට අමතර තොරතුරු සඳහා සබැඳි ඇත.


කිහිප වතාවක්ම පැමිණි එක් දෙයක් (සහ එය PEP 275 හි දැකිය හැකිය, එය සත්‍ය නිර්දේශයක් ලෙස කපා හැර තිබුනද), ඔබට නඩු 4 ක් හැසිරවීමට කේත පේළි 8 ක් තිබීම ගැන කරදර වන්නේ නම්, එදිරිව 6 ඔබට සී හෝ බෑෂ් හි ඇති රේඛා, ඔබට මෙය සැමවිටම ලිවිය හැකිය:

if x == 1: print('first')
elif x == 2: print('second')
elif x == 3: print('third')
else: print('did not place')

මෙය PEP 8 විසින් හරියටම ධෛර්යමත් නොකෙරේ, නමුත් එය කියවිය හැකි අතර එය ඒකාකාරී නොවේ.


PEP 3103 ප්‍රතික්ෂේප වී දශකයකට වැඩි කාලයක් තිස්සේ, C- විලාසිතාවේ සිද්ධි ප්‍රකාශ නිකුත් කිරීම හෝ Go හි තරමක් ප්‍රබල අනුවාදය පවා මිය ගොස් ඇතැයි සැලකේ; කවුරුහරි එය පයිතන් අදහස් හෝ -දෙව් මත ගෙන එන විට, ඔවුන් පැරණි තීරණයට යොමු කරනු ලැබේ.

කෙසේ වෙතත්, සෑම වසර කිහිපයකට වරක් පූර්ණ එම්එල්-රටා රටා ගැලපීම පිළිබඳ අදහස පැන නගී, විශේෂයෙන් ස්විෆ්ට් සහ රස්ට් වැනි භාෂාවන් එය භාවිතා කර ඇති හෙයින්. ගැටළුව වන්නේ වීජීය දත්ත වර්ග නොමැතිව රටා ගැලපීමෙන් වැඩි ප්‍රයෝජනයක් ලබා ගැනීම දුෂ්කර වීමයි. ගයිඩෝ මෙම අදහසට අනුකම්පා කර ඇති අතර, කිසිවෙකු පයිතන්ට හොඳින් ගැලපෙන යෝජනාවක් ඉදිරිපත් කර නැත. (ඔබට මගේ 2014 ස්ට්රෝමන් කියවිය හැකිය උදාහරණයක් සඳහා.) මෙම සමඟ වෙනස් විය හැකි dataclass3.7 හා වඩාත් බලවත් සඳහා යම් යම් කඩින් කඩ යෝජනා enumමුදලක් වර්ග හැසිරවීමට, හෝ (ප්රකාශය-දේශීය සබඳතා විවිධ වර්ගවල විවිධ යෝජනා වැනි සමග පී.ඊ.පී. 3150 , හෝ -අයිඩියස් හි දැනට සාකච්ඡා කෙරෙන යෝජනා මාලාවක්). නමුත් මෙතෙක් එය එසේ වී නැත.

පර්ල් 6 විලාසිතාවේ ගැලපීම සඳහා ඉඳහිට යෝජනා ද ඇත, එය මූලික වශයෙන් රීජෙක්ස් elifසිට තනි පිටත් කිරීමේ වර්ග මාරුව දක්වා සියල්ලේ මිෂ්මාෂ් ය .


16

ඔබ "ස්විචය" ලෙස අමතර ප්‍රකාශයක් සොයන්නේ නම්, මම පයිතන් දිගු කරන පයිතන් මොඩියුලයක් සාදන ලදී. එය හැඳින්වේ ESPY "පයිතන් සඳහා වැඩි දියුණු කළ ව්‍යුහය" ලෙස අතර එය පයිතන් 2.x සහ පයිතන් 3.x යන දෙකටම ලබා ගත හැකිය.

උදාහරණයක් ලෙස, මෙම අවස්ථාවේදී, පහත දැක්වෙන කේතය මඟින් ස්විච් ප්‍රකාශයක් කළ හැකිය:

macro switch(arg1):
    while True:
        cont=False
        val=%arg1%
        socket case(arg2):
            if val==%arg2% or cont:
                cont=True
                socket
        socket else:
            socket
        break

එය මේ ආකාරයෙන් භාවිතා කළ හැකිය:

a=3
switch(a):
    case(0):
        print("Zero")
    case(1):
        print("Smaller than 2"):
        break
    else:
        print ("greater than 1")

එබැවින් එස්පී විසින් එය පයිතන් භාෂාවෙන් පරිවර්තනය කරයි:

a=3
while True:
    cont=False
    if a==0 or cont:
        cont=True
        print ("Zero")
    if a==1 or cont:
        cont=True
        print ("Smaller than 2")
        break
    print ("greater than 1")
    break

ඉතා සිසිල්, නමුත් while True:ජනනය කරන ලද පයිතන් කේතයේ ඉහළින් ඇති ලක්ෂ්‍යය කුමක්ද? එය අනිවාර්යයෙන් ම ගහමු breakජනන Python කේත පතුලේ, ඒ නිසා එය දෙකම මට පෙනේ while True:සහ breakඉවත් කිරීමට හැකි වුණා. තවද, contපරිශීලකයා තමන්ගේම කේතයකින් එම නමම භාවිතා කරන්නේ නම් එහි නම වෙනස් කිරීමට ESPY දක්ෂද ? ඕනෑම අවස්ථාවක, මට වැනිලා පයිතන් භාවිතා කිරීමට අවශ්‍යයි, එබැවින් මම මෙය භාවිතා නොකරමි, නමුත් එය සිසිල් කිසිවක් අඩු නොවේ. සිසිල්බව සඳහා +1.
ArtOfWarfare

RArtOfWarfare while True:සහ breaks වලට හේතුව වීමට ඉඩ හැරීම නමුත් වැටීම අවශ්‍ය නොවේ.
සොලමන් උකෝ

මෙම මොඩියුලය තවමත් තිබේද?
සොලමන් උකෝ

15

පොදු ස්විච් ව්‍යුහයක් බව මට පෙනී ගියේය:

switch ...parameter...
case p1: v1; break;
case p2: v2; break;
default: v3;

පහත පරිදි පයිතන්හි ප්‍රකාශ කළ හැකිය:

(lambda x: v1 if p1(x) else v2 if p2(x) else v3)

හෝ පැහැදිලි ආකාරයකින් සංයුති කර ඇත:

(lambda x:
     v1 if p1(x) else
     v2 if p2(x) else
     v3)

ප්‍රකාශයක් වෙනුවට පයිතන් අනුවාදය ප්‍රකාශනයක් වන අතර එය අගයක් තක්සේරු කරයි.


එසේම ... පරාමිතිය ... සහ p1 (x) කෙසේද parameterසහp1==parameter
බොබ් ස්ටේන්

@ බොබ්ස්ටයින්-විසිබෝන් හායි, මගේ පයිතන් සැසිය තුළ ක්‍රියාත්මක වන උදාහරණයක් මෙන්න: f = lambda x: 'a' if x==0 else 'b' if x==1 else 'c' . මම පසුව ඇමතූ විට f(2), මට ලැබුණා 'c'; f(1), 'b'; සහ f(0), 'a'. P1 (x) සම්බන්ධයෙන් ගත් කල, එය පුරෝකථනයක් දක්වයි; එය නැවත පැමිණෙන තාක් කල් Trueහෝ False, එය ක්‍රියාකාරී ඇමතුමක් හෝ ප්‍රකාශනයක් වුවද එය හොඳයි.
ලියෝ

@ බොබ්ස්ටයින්-වීසිබෝන් ඔව්, ඔබ හරි! ස්තූතියි :) බහු-පේළි ප්‍රකාශනය වැඩ කිරීමට නම්, ඔබේ යෝජනාවට අනුව හෝ මගේ නවීකරණය කරන ලද උදාහරණයේ දී මෙන් වරහන් වර්‍ග තැබිය යුතුය.
ලියෝ

විශිෂ්ටයි. දැන් මම පරෙන්ස් පිළිබඳ මගේ සියලු අදහස් මකා දමමි.
බොබ් ස්ටයින්

13

ගූගල් සෙවුමේ කොතැනකවත් මා සොයන සරල පිළිතුර මට හමු නොවීය. නමුත් මම එය කෙසේ හෝ හදුනා ගතිමි. එය ඇත්තෙන්ම තරමක් සරල ය. එය පළ කිරීමට තීරණය කළ අතර, වෙනත් කෙනෙකුගේ හිසෙහි සීරීම් කිහිපයක් වළක්වා ගත හැකිය. යතුර සරලව "in" සහ tuples වේ. RANDOM fall-through ඇතුළුව වැටීම හරහා මාරුවීමේ ප්‍රකාශන හැසිරීම මෙන්න.

l = ['Dog', 'Cat', 'Bird', 'Bigfoot',
     'Dragonfly', 'Snake', 'Bat', 'Loch Ness Monster']

for x in l:
    if x in ('Dog', 'Cat'):
        x += " has four legs"
    elif x in ('Bat', 'Bird', 'Dragonfly'):
        x += " has wings."
    elif x in ('Snake',):
        x += " has a forked tongue."
    else:
        x += " is a big mystery by default."
    print(x)

print()

for x in range(10):
    if x in (0, 1):
        x = "Values 0 and 1 caught here."
    elif x in (2,):
        x = "Value 2 caught here."
    elif x in (3, 7, 8):
        x = "Values 3, 7, 8 caught here."
    elif x in (4, 6):
        x = "Values 4 and 6 caught here"
    else:
        x = "Values 5 and 9 caught in default."
    print(x)

සපයයි:

Dog has four legs
Cat has four legs
Bird has wings.
Bigfoot is a big mystery by default.
Dragonfly has wings.
Snake has a forked tongue.
Bat has wings.
Loch Ness Monster is a big mystery by default.

Values 0 and 1 caught here.
Values 0 and 1 caught here.
Value 2 caught here.
Values 3, 7, 8 caught here.
Values 4 and 6 caught here
Values 5 and 9 caught in default.
Values 4 and 6 caught here
Values 3, 7, 8 caught here.
Values 3, 7, 8 caught here.
Values 5 and 9 caught in default.

හරියටම මෙහි වැටීම කොහිද?
ජොනස් ෂෝෆර්

අපොයි! එහි වැටීමක් ඇත, නමුත් මම තවදුරටත් ස්ටැක් පිටාර ගැලීමට දායක නොවෙමි. ඔවුන්ට කිසිසේත් කැමති නැත. මම අන් අයගේ දායකත්වයට කැමතියි, නමුත් ස්ටැකෝවර්ෆ්ලෝ පමණක් නොවේ. ඔබ FUNCTIONALITY සඳහා වැටීම භාවිතා කරන්නේ නම්, ඔබ ස්විචයක විවේක ප්‍රකාශයක් ලබා ගන්නා තෙක් ස්විචයක එක් ප්‍රකාශයක (සියල්ල අල්ලා ගන්න) යම් යම් කොන්දේසි සියල්ල අල්ලා ගැනීමට ඔබට අවශ්‍යය.
ජේ. ඩී. ග්‍රැහැම්

2
මෙහිදී "බල්ලා" සහ "බළලා" යන අගයන් දෙකම වැටී ඇති අතර ඒවා හසුරුවනු ලබන්නේ එකම ක්‍රියාකාරීත්වයෙනි, ඒවා අර්ථ දැක්වෙන්නේ "කකුල් හතරක්" ඇති බවය. එය බිඳවැටීමකට සමාන ABSTRACT හා විවේකයක් සිදුවන එකම සිද්ධි ප්‍රකාශය මගින් වෙනස් අගයන් හසුරුවයි.
ජේ. ඩී. ග්‍රැහැම්

@JDGraham මම Jonas ක්රමලේඛකයෙක් ඉඳහිට ලිවීම් අමතක වන විට සිදුවන, fallthrough තවත් අංගයක් අදහස් හිතන්නේ breakසඳහා වන කේත අවසානයේ දී case. නමුත් මම හිතන්නේ අපට එවැනි "පසුබෑමක්" අවශ්‍ය නොවේ :)
මිහායිල් බැට්සර්

12

මම භාවිතා කරන විසඳුම්:

මෙහි පළ කර ඇති විසඳුම් 2 ක එකතුවක් වන අතර එය කියවීමට පහසු වන අතර පෙරනිමි සඳහා සහාය වේ.

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}.get(whatToUse, lambda x: x - 22)(value)

කොහෙද

.get('c', lambda x: x - 22)(23)

"lambda x: x - 2"ආ ict ාව දෙස බලා එය භාවිතා කරයිx=23

.get('xxx', lambda x: x - 22)(44)

මෙම dict තුළ සොයා හා පෙරනිමි භාවිතා කරන්නේ නැත "lambda x: x - 22"සමග x=44.


10
# simple case alternative

some_value = 5.0

# this while loop block simulates a case block

# case
while True:

    # case 1
    if some_value > 5:
        print ('Greater than five')
        break

    # case 2
    if some_value == 5:
        print ('Equal to five')
        break

    # else case 3
    print ( 'Must be less than 5')
    break

10
def f(x):
    dictionary = {'a':1, 'b':2, 'c':3}
    return dictionary.get(x,'Not Found') 
##Returns the value for the letter x;returns 'Not Found' if x isn't a key in the dictionary

ඔබගේ කේතය පිළිබඳ කෙටි විස්තරයක් සහ එය පළ කළ ප්‍රශ්නය විසඳන ආකාරය සලකා බලන්න
හෙන්රි වුඩි

හරි, මම දැන් ඒ සඳහා අදහස් දැක්වීමක් එකතු කළා.
වික්යාත් අගර්වාල්

8

මම කැමතියි මාක් බීස්ගේ පිළිතුරට

සිට xවිචල්‍යය දෙවරක් භාවිතා කළ යුතු , මම ලැම්බඩා ශ්‍රිත පරාමිති රහිත ලෙස වෙනස් කළෙමි.

මට දුවන්න වෙනවා results[value](value)

In [2]: result = {
    ...:   'a': lambda x: 'A',
    ...:   'b': lambda x: 'B',
    ...:   'c': lambda x: 'C'
    ...: }
    ...: result['a']('a')
    ...: 
Out[2]: 'A'

In [3]: result = {
    ...:   'a': lambda : 'A',
    ...:   'b': lambda : 'B',
    ...:   'c': lambda : 'C',
    ...:   None: lambda : 'Nothing else matters'

    ...: }
    ...: result['a']()
    ...: 
Out[3]: 'A'

සංස්කරණය කරන්න:None ශබ්ද කෝෂ සමඟ ටයිප් භාවිතා කළ හැකි බව මම දුටුවෙමි . එබැවින් මෙය අනුකරණය කරනු ඇතswitch ; case else


කිසිවක් නඩුව සරලව අනුකරණය result[None]()කරන්නේ නැද්ද?
බොබ් ස්ටයින්

ඔව්, හරියටම. මම කිව්වේresult = {'a': 100, None:5000}; result[None]
ගුනීසස්

4
කිසිවෙකු සිතන්නේ නැතැයි පරීක්ෂා කිරීම None:හරියට හැසිරෙන්නේ නැත default:.
බොබ් ස්ටයින්

7
def f(x):
     return 1 if x == 'a' else\
            2 if x in 'bcd' else\
            0 #default

කෙටි හා කියවීමට පහසු, පෙරනිමි අගයක් ඇති අතර කොන්දේසි සහ ප්‍රතිලාභ අගයන් දෙකෙහිම ප්‍රකාශන සඳහා සහය දක්වයි.

කෙසේ වෙතත්, එය ශබ්ද කෝෂයක් සමඟ ඇති විසඳුමට වඩා අඩු කාර්යක්ෂම වේ. උදාහරණයක් ලෙස, පෙරනිමි අගය ලබා දීමට පෙර පයිතන්ට සියලු කොන්දේසි පරිලෝකනය කළ යුතුය.


7

ඔබට යවන ලද නියෝගයක් භාවිතා කළ හැකිය:

#!/usr/bin/env python


def case1():
    print("This is case 1")

def case2():
    print("This is case 2")

def case3():
    print("This is case 3")


token_dict = {
    "case1" : case1,
    "case2" : case2,
    "case3" : case3,
}


def main():
    cases = ("case1", "case3", "case2", "case1")
    for case in cases:
        token_dict[case]()


if __name__ == '__main__':
    main()

ප්‍රතිදානය:

This is case 1
This is case 3
This is case 2
This is case 1

7

සරල, පරීක්ෂා කර නැත; සෑම කොන්දේසියක්ම ස්වාධීනව ඇගයීමට ලක් කරනු ලැබේ: බිඳවැටීමක් නොමැත, නමුත් සියලු අවස්ථා ඇගයීමට ලක් කෙරේ (මාරුවීමේ ප්‍රකාශනය ඇගයීමට ලක් කරනු ලබන්නේ එක් වරක් පමණි), විවේක ප්‍රකාශයක් නොමැති නම්. උදාහරණයක් වශයෙන්,

for case in [expression]:
    if case == 1:
        print(end='Was 1. ')

    if case == 2:
        print(end='Was 2. ')
        break

    if case in (1, 2):
        print(end='Was 1 or 2. ')

    print(end='Was something. ')

පිටපත් Was 1. Was 1 or 2. Was something. (Dammit! ඇයි මම පේළිගත කේතයන් තුළ whitespace අවර ඇත නොහැකි?) නම් expressionඇගයීමට කිරීමට 1, Was 2.නම් expressionකිරීමට ඇගයීමට 2හෝ Was something.නම් expressionවෙන දෙයක් කිරීමට ඇගයීමට.


1
හොඳයි, වැඩ හරහා වැටීම, නමුත් do_default වෙත යාමට පමණි.
syockit

5

නිර්වචනය:

def switch1(value, options):
  if value in options:
    options[value]()

සිතියමකට සම්බන්ධ කර ඇති අවස්ථා සමඟ තරමක් සරල වාක්‍ය ඛණ්ඩයක් භාවිතා කිරීමට ඔබට ඉඩ සලසයි:

def sample1(x):
  local = 'betty'
  switch1(x, {
    'a': lambda: print("hello"),
    'b': lambda: (
      print("goodbye," + local),
      print("!")),
    })

මම "ලැම්බඩා:" ඉවත් කිරීමට ඉඩ සලසන අයුරින් ස්විචය නැවත අර්ථ දැක්වීමට උත්සාහ කළ නමුත් එය අත්හැරියෙමි. අර්ථ දැක්වීම වෙනස් කිරීම:

def switch(value, *maps):
  options = {}
  for m in maps:
    options.update(m)
  if value in options:
    options[value]()
  elif None in options:
    options[None]()

එකම කේතයකට අවස්ථා කිහිපයක් සිතියම් ගත කිරීමට සහ පෙරනිමි විකල්පයක් සැපයීමට මට ඉඩ දී ඇත:

def sample(x):
  switch(x, {
    _: lambda: print("other") 
    for _ in 'cdef'
    }, {
    'a': lambda: print("hello"),
    'b': lambda: (
      print("goodbye,"),
      print("!")),
    None: lambda: print("I dunno")
    })

ප්‍රතිවර්තනය කරන ලද සෑම නඩුවක්ම එහි ශබ්ද කෝෂයේ තිබිය යුතුය; ස්විචය () අගය බැලීමට පෙර ශබ්ද කෝෂ ඒකාබද්ධ කරයි. එය මා කැමති ප්‍රමාණයට වඩා තවමත් කැතයි, නමුත් එයට සියලු යතුරු හරහා ලූපයක් වෙනුවට ප්‍රකාශනය මත හැෂ් බැලීමක් භාවිතා කිරීමේ මූලික කාර්යක්ෂමතාව ඇත.


5

මම හිතන්නේ හොඳම ක්‍රමය ඔබේ කේතය පරීක්ෂා කර බැලීමට පයිතන් භාෂා මෝඩයන් භාවිතා කිරීමයි . පෙර පිළිතුරු වල පෙන්වා ඇති පරිදි, මම පයිතන් ව්‍යුහයන්ගෙන් සහ භාෂාවෙන් ප්‍රයෝජන ගැනීමට ශබ්ද කෝෂ භාවිතා කරන අතර "කේස්" කේතය විවිධ ක්‍රම වලින් හුදකලා කර තබමි. පහළින් පංතියක් ඇත, නමුත් ඔබට කෙලින්ම මොඩියුලයක්, ග්ලෝබල් සහ කාර්යයන් භාවිතා කළ හැකිය. පන්තියට හුදකලාව පරීක්ෂා කළ හැකි ක්‍රම තිබේ . ඔබගේ අවශ්‍යතා මත පදනම්ව, ඔබට ස්ථිතික ක්‍රම සහ ගුණාංග සමඟ සෙල්ලම් කළ හැකිය.

class ChoiceManager:

    def __init__(self):
        self.__choice_table = \
        {
            "CHOICE1" : self.my_func1,
            "CHOICE2" : self.my_func2,
        }

    def my_func1(self, data):
        pass

    def my_func2(self, data):
        pass

    def process(self, case, data):
        return self.__choice_table[case](data)

ChoiceManager().process("CHOICE1", my_data)

"__Choice_table" හි යතුරු ලෙස පන්ති ද භාවිතා කරමින් මෙම ක්‍රමයේ වාසිය ලබා ගත හැකිය . මේ ආකාරයෙන් ඔබට අනිසි අපයෝජනයන් වළක්වා ගත හැකි අතර සියල්ල පිරිසිදුව හා පරීක්‍ෂා කළ හැකිය.

ඔබට ජාලයෙන් හෝ ඔබේ MQ වෙතින් පණිවිඩ හෝ පැකට් ගොඩක් සැකසිය යුතු යැයි සිතමු. සෑම පැකට්ටුවකටම තමන්ගේම ව්‍යුහයක් සහ කළමනාකරණ කේතයක් ඇත (සාමාන්‍ය ආකාරයෙන්). ඉහත කේතය සමඟ මෙවැනි දෙයක් කළ හැකිය:

class PacketManager:

    def __init__(self):
        self.__choice_table = \
        {
            ControlMessage : self.my_func1,
            DiagnosticMessage : self.my_func2,
        }

    def my_func1(self, data):
        # process the control message here
        pass

    def my_func2(self, data):
        # process the diagnostic message here
        pass

    def process(self, pkt):
        return self.__choice_table[pkt.__class__](pkt)

pkt = GetMyPacketFromNet()
PacketManager().process(pkt)


# isolated test or isolated usage example
def test_control_packet():
    p = ControlMessage()
    PacketManager().my_func1(p)

එබැවින් කේත ප්‍රවාහයේ සංකීර්ණත්වය ව්‍යාප්ත නොවන නමුත් එය කේත ව්‍යුහයෙන් විදහා දක්වයි .


ඇත්තටම කැතයි ... කියවීමේදී ස්විච් කේස් ඉතා පිරිසිදුයි. එය පයිතන් තුළ ක්‍රියාත්මක නොවන්නේ මන්දැයි තේරුම් ගත නොහැක.
jmcollin92

Nd ඇන්ඩික්ලිෆ්ටන්: මට කණගාටුයි ... උදාහරණයක්? ඔබට බහුවිධ තීරණ ගැනීමේ කේතයක් තිබිය යුතු සෑම අවස්ථාවකම සිතන්න, ඔබට මෙම ක්‍රමය ක්‍රියාත්මක කළ හැකිය.
J_Zar

@ jmcollin92: ස්විච් ප්‍රකාශය විශ්වාස කළ හැකි ය, මම එකඟ වෙමි. කෙසේ වෙතත් ක්‍රමලේඛකයා නැවත භාවිතා කළ නොහැකි ඉතා දිගු ප්‍රකාශ සහ කේත ලිවීමට නැඹුරු වේ. මා විස්තර කළ ආකාරය පරීක්ෂා කිරීමට වඩා පිරිසිදු වන අතර නැවත භාවිතා කළ හැකි IMHO වේ.
J_Zar

@J_Zar: නැවත. උදාහරණයක් සඳහා මගේ ඉල්ලීම: ඔව්, මට එය ලැබුණි, නමුත් මෙය විශාල කේත කැබැල්ලක සන්දර්භය තුළට දැමීමට මම වෙහෙසෙමි. සැබෑ ලෝක තත්වයකදී මම මෙය භාවිතා කරන්නේ කෙසේදැයි ඔබට පෙන්විය හැකිද?
ඇන්ඩි ක්ලිෆ්ටන්

1
Nd ඇන්ඩික්ලිෆ්ටන්: මට කණගාටුයි, මම ප්‍රමාදයි නමුත් මම උදාහරණ කිහිපයක් පළ කළෙමි.
J_Zar

5

ග්‍රෙග් හෙව්ගිල්ගේ පිළිතුර පුළුල් කිරීම - සැරසිලි කරුවෙකු භාවිතයෙන් අපට ශබ්ද කෝෂ විසඳුම සංයුක්ත කළ හැකිය:

def case(callable):
    """switch-case decorator"""
    class case_class(object):
        def __init__(self, *args, **kwargs):
            self.args = args
            self.kwargs = kwargs

        def do_call(self):
            return callable(*self.args, **self.kwargs)

return case_class

def switch(key, cases, default=None):
    """switch-statement"""
    ret = None
    try:
        ret = case[key].do_call()
    except KeyError:
        if default:
            ret = default.do_call()
    finally:
        return ret

මෙය පසුව @case-decorator සමඟ භාවිතා කළ හැකිය

@case
def case_1(arg1):
    print 'case_1: ', arg1

@case
def case_2(arg1, arg2):
    print 'case_2'
    return arg1, arg2

@case
def default_case(arg1, arg2, arg3):
    print 'default_case: ', arg1, arg2, arg3

ret = switch(somearg, {
    1: case_1('somestring'),
    2: case_2(13, 42)
}, default_case(123, 'astring', 3.14))

print ret

ශුභාරංචිය නම් මෙය දැනටමත් NeoPySwitch -module හි සිදු කර ඇති බවයි . පයිප්ප භාවිතයෙන් ස්ථාපනය කරන්න:

pip install NeoPySwitch

5

ශබ්ද කෝෂ භාවිතා කරන මා භාවිතා කිරීමට නැඹුරු වන විසඳුමක් නම්:

def decision_time( key, *args, **kwargs):
    def action1()
        """This function is a closure - and has access to all the arguments"""
        pass
    def action2()
        """This function is a closure - and has access to all the arguments"""
        pass
    def action3()
        """This function is a closure - and has access to all the arguments"""
        pass

   return {1:action1, 2:action2, 3:action3}.get(key,default)()

මෙය සෑම විටම කාර්යයන් ඇගයීමට උත්සාහ නොකිරීමේ වාසියක් ඇති අතර, අභ්‍යන්තර ශ්‍රිතයට අවශ්‍ය සියලු තොරතුරු බාහිර ශ්‍රිතයට ලැබෙන බවට ඔබ සහතික විය යුතුය.


5

"අපට පයිතන්හි ස්විචයක් නොමැත, එය මේ ආකාරයෙන් කරන්න" යනුවෙන් පවසා ඇති පිළිතුරු රාශියක් මේ වන විට තිබේ. කෙසේ වෙතත්, ස්විච් ප්‍රකාශය පහසුවෙන්ම අනිසි ලෙස භාවිතා කළ හැකි ඉදිකිරීමක් බව පෙන්වා දීමට මම කැමැත්තෙමි. කාරණය අනුව:

def ToUpper(lcChar):
    if (lcChar == 'a' or lcChar == 'A'):
        return 'A'
    elif (lcChar == 'b' or lcChar == 'B'):
        return 'B'
    ...
    elif (lcChar == 'z' or lcChar == 'Z'):
        return 'Z'
    else:
        return None        # or something

දැන්, ඔබ හැකි මාරු-ප්රකාශය සමග මෙය (Python එක් ඉදිරිපත් නම්) නමුත් මේ දැන් හොදින් කරන ක්රම තිබෙනවා නිසා ඔබ ඔබේ කාලය නාස්ති කළ කියලා. නැතහොත්, ඔබට අඩු පැහැදිළි යමක් තිබේ:

def ConvertToReason(code):
    if (code == 200):
        return 'Okay'
    elif (code == 400):
        return 'Bad Request'
    elif (code == 404):
        return 'Not Found'
    else:
        return None

කෙසේ වෙතත්, මෙවැනි ක්‍රියාකාරිත්වයක් ශබ්දකෝෂයකින් හැසිරවිය හැකි අතර එය වේගවත්, අඩු සංකීර්ණ, දෝෂ වලට ගොදුරු වීමේ අවදානම අඩු හා වඩා සංයුක්ත වනු ඇත.

ස්විච් ප්‍රකාශ සඳහා “භාවිතා කිරීමේ අවස්ථා” වලින් බහුතරයක් මෙම අවස්ථා දෙකෙන් එකකට වැටෙනු ඇත; ඔබ ඔබේ ගැටලුව ගැන තරයේ සිතුවා නම් එකක් භාවිතා කිරීමට ඇත්තේ ඉතා අල්ප හේතුවකි.

ඉතින්, "මම පයිතන් වෙත මාරු වන්නේ කෙසේද?" යනුවෙන් අසනවාට වඩා, සමහර විට අප ඇසිය යුත්තේ, "මට පයිතන් තුළට මාරුවීමට අවශ්‍ය ඇයි?" මන්ද එය බොහෝ විට වඩාත් සිත්ගන්නාසුලු ප්‍රශ්නය වන අතර බොහෝ විට ඔබ ගොඩනඟන ඕනෑම දෙයක් සැලසුම් කිරීමේදී අඩුපාඩු හෙළි කරනු ඇත.

දැන්, ස්විචයන් කිසි විටෙකත් භාවිතා නොකළ යුතු යැයි නොකියයි. රාජ්‍ය යන්ත්‍ර, ලෙක්සර්, පාර්සර් සහ ඔටෝමැටා යන සියල්ලම ඒවා යම් ප්‍රමාණයකට භාවිතා කරන අතර, පොදුවේ ගත් කල, ඔබ සමමිතික ආදානයකින් ආරම්භ කර අසමමිතික නිමැවුමකට ගිය විට ඒවා ප්‍රයෝජනවත් වේ; ඔබේ කේතයේ නියපොතු පොකුරක් දකින නිසා ඔබ ස්විචය මිටියක් ලෙස භාවිතා නොකරන බවට වග බලා ගත යුතුය.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.