Python: analyzing complex statements at runtime

I am wondering if there is a way to get some meta information about interpreting the python operator at runtime.

Suppose this is a complex instruction of some individual operators related to or (A, B, ... are Boolean functions)

if A or B and ((C or D and E) or F) or G and H:

and I want to know which part of the instruction causes an expression for Truth, so I can do something with this knowledge. In this example, there would be 3 possible candidates:

A
B and ((C or D and E) or F)
G and H

And in the second case, I would like to know if it was a value (C or D and E)or Fthat was evaluated as True and so on ...

Is there an indiscriminate way? Can I somehow connect to the interpreter or use the verification module in a way that I have not found? I don’t want to debug, it really knows what part of this or-chain the statement called at runtime.

- : , , - , . , .
, . 3000 if-elif, ,

if obj.attr1 < 23 and (is_something(obj.attr10) or eats_spam_for_breakfast(obj)):
    return 'Category1'
elif obj.attr3 == 'Welcome Home' or count_something(obj) >= 2:
    return 'Category2a'
elif ...

, , , , , , (- or ). , 1000 . 200 .

!

2: . , !

+3
5

:

if A or B and ((C or D and E) or F) or G and H:

, :

e = Evaluator()
if e('A or B and ((C or D and E) or F) or G and H'):

...? , ! -). Evaluator __call__ compile , eval ( dict globals ) pseudo- dict locals, ( , , ;-), , . Python and or, , , ( ) - X or Y or Z, ( ) , X and Y and Z .

? , , , , Evaluator , ! -)

: Evaluator :

import inspect
import random

class TracingDict(object):

  def __init__(self, loc, glob):
    self.loc = loc
    self.glob = glob
    self.vars = []

  def __getitem__(self, name):
    try: v = self.loc[name]
    except KeyError: v = self.glob[name]
    self.vars.append((name, v))
    return v


class Evaluator(object):

  def __init__(self):
    f = inspect.currentframe()
    f = inspect.getouterframes(f)[1][0]
    self.d = TracingDict(f.f_locals, f.f_globals)

  def __call__(self, expr):
    return eval(expr, {}, self.d)


def f(A, B, C, D, E):
  e = Evaluator()
  res = e('A or B and ((C or D and E) or F) or G and H')
  print 'R=%r from %s' % (res, e.d.vars)

for x in range(20):
  A, B, C, D, E, F, G, H = [random.randrange(2) for x in range(8)]
  f(A, B, C, D, E)

:

R=1 from [('A', 1)]
R=1 from [('A', 1)]
R=1 from [('A', 1)]
R=1 from [('A', 0), ('B', 1), ('C', 1)]
R=1 from [('A', 1)]
R=1 from [('A', 0), ('B', 0), ('G', 1), ('H', 1)]
R=1 from [('A', 1)]
R=1 from [('A', 1)]
R=1 from [('A', 0), ('B', 1), ('C', 1)]
R=1 from [('A', 1)]
R=1 from [('A', 0), ('B', 1), ('C', 1)]
R=1 from [('A', 1)]
R=1 from [('A', 1)]
R=1 from [('A', 1)]
R=0 from [('A', 0), ('B', 0), ('G', 0)]
R=1 from [('A', 1)]
R=1 from [('A', 1)]
R=1 from [('A', 1)]
R=0 from [('A', 0), ('B', 0), ('G', 0)]
R=1 from [('A', 0), ('B', 1), ('C', 1)]

, ( 50% ) A , . A , B - B , G , B , C.

+3

, Python True False :

: or and .

Python -
, :

A = 1
B = 0
result = B or A # result == 1
+1

"" , , - . "" ": , " debug "" know ".

, , , , (?), - , , "", - ?

, , A, B, C .. , :

part1 = A
part2 = B and ((C or D and E) or F)
part3 = G and H
whodunit = "1" if part1 else "2" if part2 else "3" if part3 else "nobody"
print "Perp is", whodunit
if part1 or part2 or part3:
    do_something()

??

Update:

"" debug ", " , , , True ( ) ""

, , , "A B", A B , A ( )? , , , "" . , , "A B", "B A"? , , ?

, Python , , , -, . part1 = yadda; part2 = blah; etc?

0

Python . sys.settrace() , , , .

, , : - Python.

, , , .

, , , - . ( , ), -. , , , .

, ...

BTW: ?

0

- (, ):

for i in ("A","B","C","D","E","F","G","H"):
    print i,self.__dict__[i]
0

Source: https://habr.com/ru/post/1723825/


All Articles