0

Sorry for the slightly obscure question title.

In essence, I need to do the following.

I have a function in Python, for example:

@Wrapper
def auselessfunction(dictionary):
    dictionary["foo"] = 3
    dictionary["bar"] = 5

I then have a decorator object which takes the function as input, e.g.

class Wrapper:
    def __init__(self,function):
        self.function = function
    def __call__(self,*args):
        self.function(*args)

I need a way to determine in the init method of the decorator what the keys of the dictionary used by the function are.

Is there a way to do this? I have been looking at function introspection and the keys themselves can be found using:

function.__code__.co_consts

but this gives all the constants used in the function body, which could be dangerous.

Thanks in advance.

Edit:

Thanks for the fast response. I can understand that my specific problem is a little bit vague. In simpler terms, what I want to do is create a decorator which, given a function that accessing certain keys from a dictionary, can then find/calculate the values for those specific keys. For example, if the dictionary represented a position in a 2D list, dictionary[0,0] would represent the current index, dictionary[0,1] represents the index directly beneath it and so on. I was wondering if there is a way for a function to accessing these keys without needing to directly access the actual position in the 2D list. I don't know whether that makes it any clearer...

E.g. Given that:

board =
[0,1,2,3,4,5],
[5,4,3,2,1,0],
[0,1,2,3,4,5],
[5,4,3,2,1,0],
[0,1,2,3,4,5],
[5,4,3,2,1,0]

dictionary[0,0] refers to 0,1,2,3,4,5,5,4.... successively, and
dictionary[0,1] refers to 5,4,3,2,1,0,0,1.... (the elements directly underneath)

To do this, I am trying to create a decorator which resolves these positions, but I only want to resolve the positions which are actually used, thus the problem.

Edit: (@aya)

I would love to give more specific code, but this is as close as I can get without knowing the answer to my original question. Ideally, I would like a solution which saves the object passed as a key every time the dictionary is accessed. The problem is that I want to know before the dictionary access method is called. The closest thing that I can think of is searching the code object returned by the function for dictionary access calls with a regular expression, or something similar involving the code object. I am sorry I can't be more helpful than that.

user2515310
  • 357
  • 3
  • 8
  • I don't see how `board` relates to `dictionary` in your example. Could you provide some example code which is closer to what you actually have, and explain what you're actually trying to achieve? – Aya Jun 26 '13 at 09:09
  • @Aya Updated question to respond – user2515310 Jun 26 '13 at 10:32
  • Okay. But can you explain what you're trying to achieve at a higher level - something along the lines of "I'm trying to write a game which has a board, and I need a function to detect which pieces..." or somesuch. – Aya Jun 26 '13 at 14:55

1 Answers1

0

I don't know what is your problem, but I'm not sure your solution is the best.

As far as I can tell, you will at least need to access the code of the function (function.__code__) and decompile it. And even so, it will not be that easy...

As of __code__.co_consts, it is only a "segment" containing the static value used in the function source code. As you notices, just inspecting it will trigger false positive. On the other hand, you will not be able to detect access to your dictionary if the key is "not constant" (variable, parameter, or obtained otherwise).

Not mentioning, finally, that your code will become (very) implementation dependent.


As you can see, there is many reserves here. As an advice, instead of asking about your attempted solution, you should post an other question mentioning your need, in order to obtain other -- more robust -- solutions. As an example, instead of wrapping your function in a decorator, you might use a custom class for dictionary, that behave like a dictionary, but with some kind of "logging" or "checking" activity if you want to prevent access to some keys. Once again, it is hard to tell without knowing what is the real problem.

Sylvain Leroux
  • 50,096
  • 7
  • 103
  • 125