0

I have a decorator function that uses sys._getframe(1).f_code to get the code object of the caller func.

The problem is that I need the caller func function object so I can access this functions attributes.

I can use eval to call the function with the code object but that does not help me.

    def decorator(func)
        def wrappe_function(*args, **kwargs):
              # Problem here, want func object not code object
              result = getattr(sys._getframe(1).f_code, "level")
              if result != "private":
                  print "Warning accessing a private func. If this funcion is changed, you will not be notified!"
              return func(*args, **kwargs)
    return decorator

    @decorator
    def x():
        print "hello"

def main()
    x()
main.level = "public"
daniel
  • 1
  • 1
  • So you're trying to access `x.level` inside the decorator? There's no need for introspection; `x` is literally being passed to `decorator` as an argument. – Aran-Fey Sep 08 '17 at 10:49
  • sorry missed a step, I want to get main attrib that calls on x – daniel Sep 08 '17 at 11:23
  • Thank you Rwaing. Exactly what iam looking for and it works fine. I probably need to train my google skills because I ahve google alot of different terms and did not find it. :) – daniel Sep 08 '17 at 11:49

1 Answers1

0

You have to change the return value of the def decorator method. Also, you should modify the logic because your code will crash, when no attribute has been defined. Also, you should set the attribute of accessibility directly in the decorator, and not as an attribute of the function - this makes more sense in my opinion, as this value should not be changed during run time. This is a sketch of a fixed version:

import sys

def decorator(level):
    def real_decorator(function):
        def wrapper(*args, **kwargs):
            if (level == "private"):
                print("Warning accessing a private func. If this funcion is changed, you will not be notified!")
            function(*args, **kwargs)
        return wrapper
    return real_decorator

@decorator(level="public")
def x():
    print ("hello")

Edit: the first version I posted had a huge error, but this version is now working.

zimmerrol
  • 4,872
  • 3
  • 22
  • 41
  • The problem here is that all functions that calls x will get level = public. I want to define som functions to have level public and other private. And sorry for the uncomplete examaple did it in a bit of a hurry. For example the user should get a warning when Calling _helper but other functions in the class should be able to use _helper without a warning being printed. == level = public/private will lead to both member functions and user calls getting the same level. I have an example where i look on the function name and compare it to a list of allowed fuctions but would like to skip a list – daniel Sep 08 '17 at 11:06