更简单的方法来检查条件?

发布于 2024-10-30 16:30:14 字数 2835 浏览 8 评论 0原文

我是 python 新手,我需要简化这个检查器。我如何将:更改

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

为:

 if  prevTime | condition |  currentTime:
    doSomething()

我尝试使用 evaluatecompile,但在创建字符串期间,日期时间对象到字符串之间存在转换( >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) )

I'm new to python and I need to simplify this checker. How can I change:

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

to something like:

 if  prevTime | condition |  currentTime:
    doSomething()

I've tried to use either evaluate or compile, but during creation of string there is conversion between datetime object to string ( str on datetime object). For example:

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

and it can't be compared.

Can someone help me with this? Below working example:

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) )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

樱花细雨 2024-11-06 16:30:14

您可以尝试制作操作员地图,如下所示:

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

You can try making a map of operators, like this:

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
中性美 2024-11-06 16:30:14

人们做这样的事情:

result= { '=': lambda a, b: a == b,
    '>': lambda a, b: a > b,
    '>=': lambda a, b: a >= b,
    etc.
    }[condition]( prevTime, currentTime )

Folks do things like this:

result= { '=': lambda a, b: a == b,
    '>': lambda a, b: a > b,
    '>=': lambda a, b: a >= b,
    etc.
    }[condition]( prevTime, currentTime )
红玫瑰 2024-11-06 16:30:14

您是否正在寻找类似的内容:

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

您的评估失败了,因为您在评估之外进行了太多计算。

当然,eval 策略本身是丑陋的;你应该使用其他答案之一;)

Are you looking for something like:

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

Your evals are failing because you're doing too much of the computation outside the eval.

Of course, the eval strategy itself is ugly; you should use one of the other answers ;)

維他命╮ 2024-11-06 16:30:14

仅当函数未返回时才设置 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

注意:其他人的“函数字典”方法是执行此操作的 Python 方法。我只是想演示您的原始函数的清理版本,它以您已经熟悉的方式工作,但流程更简单。

You're only setting c1 = True if the function doesn't return, so it's guaranteed to be True at the end of the function. Factor it out.

The output of this function will be identical:

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

Note: everyone else's "dict of functions" approach is the Pythonic way to do this. I just wanted to demonstrate a cleaned-up version of your original function that works in a way already familiar to you but with a more straightforward flow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文