0

私はPythonを初めて使用するので、このチェッカーを単純化する必要があります。どうすれば変更できますか:

...
if c == '>' and ( prevTime > currentTime ):
    c2 = True
elif c == '>=' and ( prevTime >= currentTime ):
    c2 = True
...

次のようなものに:

 if  prevTime | condition |  currentTime:
    doSomething()

評価またはコンパイルのいずれかを使用しようとしましたが、文字列の作成中に、日時オブジェクトから文字列(日時オブジェクトのstr)への変換があります。例えば:

>>> 'result = %s %s %s' % (datetime.now(), '>', datetime.utcfromtimestamp(41))
'result = 2011-04-07 14:13:34.819317 > 1970-01-01 00:00:41'

比較することはできません。

誰かがこれを手伝ってくれますか?以下の実例:

def checkEvent( prevEvent, currentEvent, prevTime, currentTime ):

    def checkCondition( condition ):

        #condition format
        #tuple ( (oldEvent, newEvent), time, ip)
        # eg: (('co', 'co'), '>=', '!=')

        c1 = c2 = False

        #check Event
        if prevEvent == condition[0][0] and currentEvent == condition[0][1]:
            c1 = True
        else:
            return False

        #check time
        if condition[1]:
            c = condition[1]

            if c == '>' and ( prevTime > currentTime ):
                c2 = True
            elif c == '>=' and ( prevTime >= currentTime ):
                c2 = True
            elif c == '<' and ( prevTime < currentTime ):
                c2 = True
            elif c == '<=' and ( prevTime <= currentTime ):
                c2 = True
            elif c == '==' and ( prevTime == currentTime ):
                c2 = True

        else:
            c2 = True


        return c1 and c2


    def add():
        print 'add'

    def changeState():
        print 'changeState'

    def finish():
        print 'finish'

    def update():
        print 'update'    


    conditions = (\
                    ( ( ( 're', 'co' ), None ),  ( add, changeState ) ),
                    ( ( ( 'ex', 'co' ), None ),  ( add, changeState ) ),
                    ( ( ( 'co', 'co' ), '<'  ),  ( add, changeState ) ),
                    ( ( ( 'co', 'co' ), '>=' ),  ( add, changeState, finish ) ),
                    ( ( ( 'co', 'co' ), '>=' ),  ( update, ) ),
                    ( ( ( 'co', 're' ), '>=' ),  ( changeState, finish ) ),
                    ( ( ( 'co', 'ex' ), '>=' ),  ( changeState, finish ) ) 
                 )  


    for condition in conditions:
        if checkCondition( condition[0] ):
            for cmd in condition[1]:
                cmd()


from datetime import datetime

checkEvent( 'co', 'co', datetime.utcfromtimestamp(41), datetime.now() )
checkEvent( 'ex', 'co', datetime.utcfromtimestamp(41), datetime.now() )
checkEvent( 'co', 'co', datetime.utcfromtimestamp(41), datetime.utcfromtimestamp(40) )
4

4 に答える 4

8

次のように、演算子のマップを作成してみてください。

import operator

compares = {
    '>': operator.gt,
    '>=': operator.ge,
    '<': operator.lt,
    '<=': operator.le,
    '==': operator.eq
}

def check(c, prev, current):
    func = compares[c]
    return func(prev, current)

print check('>', 5, 3)  # prints: True
print check('>=', 5, 5) # prints: True
print check('<', 3, 5)  # prints: True
print check('<=', 3, 3) # prints: True
print check('==', 7, 7) # prints: True
于 2011-04-07T13:07:25.097 に答える
5

人々はこのようなことをします:

result= { '=': lambda a, b: a == b,
    '>': lambda a, b: a > b,
    '>=': lambda a, b: a >= b,
    etc.
    }[condition]( prevTime, currentTime )
于 2011-04-07T13:07:01.153 に答える
0

次のようなものをお探しですか?

>>> eval('datetime.now() %s datetime.utcfromtimestamp(41)' % '>')
True

評価の外部で多くの計算を行っているため、評価は失敗しています。

もちろん、評価戦略自体は醜いです。他の答えの1つを使用する必要があります;)

于 2011-04-07T13:10:47.863 に答える
0

c1 = True関数が返されない場合にのみ設定するので、関数の最後でTrueであることが保証されます。それを除外します。

この関数の出力は同じになります。

def checkEvent( prevEvent, currentEvent, prevTime, currentTime ):

    def checkCondition( condition ):

        #condition format
        #tuple ( (oldEvent, newEvent), time, ip)
        # eg: (('co', 'co'), '>=', '!=')

        #check Event
        if not (prevEvent == condition[0][0] and currentEvent == condition[0][1]):
            return False

        #check time
        c = condition[1]
        if not condition[1]:
            return True

        if c == '>' and ( prevTime > currentTime ):
            return True
        elif c == '>=' and ( prevTime >= currentTime ):
            return True
        elif c == '<' and ( prevTime < currentTime ):
            return True
        elif c == '<=' and ( prevTime <= currentTime ):
            return True
        elif c == '==' and ( prevTime == currentTime ):
            return True

        return False

注:他のすべての人の「関数のdict」アプローチは、これを行うためのPythonの方法です。すでにおなじみの方法で機能するが、より単純なフローで機能する、元の関数のクリーンアップバージョンを示したかっただけです。

于 2011-04-07T13:12:14.583 に答える