I try to figure out the meaning of decorator in python, and practice a snippet as below on python console:
def print_my_name(name):
print "I am %s" %(name())
#print_my_name
def my_name():
return "Hans"
And it will come out with,
I am Hans
It never happens on normal functions.
Could anybody tell me how it works?
Thank you
A decorator takes the function definition and creates a new function that executes this function and transforms the result.
The shortest explanation that I can give is that decorators wrap your function in another function that returns a function.
This code, for example:
#decorate
def foo(a):
print a
would be equivalent to this code if you remove the decorator syntax:
def bar(a):
print a
foo = decorate(bar)
Decorators sometimes take parameters, which are passed to the dynamically generated functions to alter their output.
Another term you should read up on is closure, as that is the concept that allows decorators to work.
Related
Magic methods in python are really magical. For example:
class DynMember:
def __getattr__(self, name: str):
def fn(self, **kwargs):
print(kwargs)
setattr(self.__class__, name, fn)
return lambda **x: fn(self, **x)
if __name__ == "__main__":
d = DynMember()
d.someFn(title="Greeting", description="Hello world!") # outputs {'title': 'Greeting', 'description': 'Hello world!'}
d.someFn(k1="value 1", k2="value 2") # outputs {'k1': 'value 1', 'k2': 'value 2'}
There was no someFn in DynMember class. The method is set on the class using __getattr__ magic method and setattr builtin method. These methods are really powerful and make classes do wonders in python. (have written a html generator only in 40 lines of code). How to achieve something similar in C++?
What you want is not supported by C++ yet, there is some third-party libraries like Qt or Boost which provide that. But (is ambiguity about what you exactly want) if you want to implement something like def fn(self, **kwargs) you can do it with Variadic Functions (Example) or Template Parameter Pack (Example) or Designated initializers from C++20 or std::map (as #alterigel mentioned on commnets).
Reflection:
How can I add reflection to a C++ application ?
Reflection for C++
KWArgs:
kwargs like arguments with Boost
Another implementation of kwargs like arguments
Yes and no. The question whether C++ support this or not is ambiguous. You can definitely create a new function on the fly - it is possible. There are two options:
Load machine code into memory or
Compile and load code at runtime.
But would you do it ? Probably not.
The main problem is that you are comparing an interpreted language with a compiled language. A compiled language needs compilation, while an interpreted language does not.
Obviously it is way easier to refer to a piece of code within the same VM than to compile and load. So because it is impractical I would say it is possible but not convenient.
See more:
Is it possible to create a function dynamically, during runtime in C++?
As mentioned elsewhere C++ doesn't support this yet. The best alternative that I can think would be to add a container to the class either publicly available or accessible through accessor functions. The container could be a map, mapping a string to a stored pointer to void. The user would then be responsible for knowing what type is stored in the pointer to void.
Here's one option of how to store it: std::map<std:string, void *> storedProperties;
I am new to python, so bear with me. I see functions in python like below:
#dag.cellfn(dag.CanSet)
def XYZ(self):
return None
whats the purpose of such functions?
# denotes a decorator function. What this means is that before your XYZ function gets called, it will first call the dag.cellfn function with 2 arguments, a reference to XYZ and dag.CanSet. The decorated function (dag.cellfn) will do whatever it was written to do and eventually call the reference function (XYZ).
Decorators are often used to minimize code repetition, say you want to wrap every one of your functions with a try/catch. The decorator will let you write the try/catch once and then execute any function inside it.
You should read the python documentation for decorators.
Suppose I have defined a function like this:
def calc():
print x
And I want to inject var x into the function's local by some ways before I calling it.
This looks like I added a keyword x and I can use x in function calc() without defining it. And what x will be is defined by the outer function who calls the calc().
Maybe this is a silly question, but I just want to know is it possible to do that?
If we can't modify it's locals before calling it, can we try another way? That is suppose we use decorator or something else to modify the func()'s definition automatically to
def clac(x):
print x
Maybe in this way, we need to play with the function's bytecode?
Can someone give some advise?
This seems like a very perverse thing to do, but it is actually possible. A reference to an undefined name compiles as a global variable reference, so we just need to call the function with a different global environment. Unfortunately, the func_globals attribute of functions is read-only, so we have to play some tricks with the function's code object. Try this:
exec calc.func_code in {'x': 'blah'}
Note that the dictionary you pass will be modified by adding a '__builtins__' slot - this allows the function to access Python's built-in functions and constants.
I am vrey new to python and have to work with a given code (not my implementation), with very limited accesses (no debugger, screen prints and such).
Assuming I have the following class:
class foo ():
def __init__(self, u, v):
#some flow
def main():
#some flow
x=1
return x
main() and foo() are in the same "file.py" file. are they connected?
and I instantiate it in the following way:
import file as A
MyFoo=A.main()
In oppose to:
MyFoo=foo()
Did I call upon the __init__ function?
If so how? I see no point where it is stimulated.
If it was indeed called (and here lies the big questions) how do I assert values for u & v?
I have tried an online compiler and still didn't manage, changing u & v values. I also read this to try and understand instantiation process in python.
It would help if you stated your overall goal, but I can offer this information: __init__ is called by Python to initialize new instances of a class. If you want it called, you should say "myfoo = foo(myu,myv)". That will cause Python to invoke __new__, which will invoke __init__ for you. You should do something with u and v inside __init__, perhaps assigning them to instance attributes, like this: "self.u = u".
Here, main() is just a normal, unbound function, not an instance function or a class function of foo, not even a static function inside foo's scope, and definitely not a mainline in the C and Java sense of "mainline." If you want it to create an instance of foo, you should put "myfoo = foo(myu,myv)" inside main(project). However, the fact that you named the function "main" suggests you don't know how mainlines work in Python. See here: What does if __name__ == "__main__": do?
When you import file as A and then say "MyFoo = A.main()", all you are doing is invoking main(), which just returns 1 and does nothing with class foo. Try printing out MyFoo. You will see that it got the return value of main (which was 1), and thus MyFoo has nothing to do with class foo.
The way you are naming things suggests you are very confused. Please say your overall goal, so we can help you more.
I have a function like this:
def foo(bar):
...
Now bar can either be a Django record or the slug pointing to a record. I need this flexibility so that I can call this function when I have the actual record at hand or am calling this from a more generic function that only has bar available as a string (pulled from a database).
I realize I can do something like:
def foo(bar):
try:
bar.pk
except AttributeError:
bar = Bar.objects.get(slug=bar)
...
But this doesn't seem elegant at all.
If I can I'd like to avoid using isinstance.
You are by definition not using Duck Typing. Duck Typing says that "if it talks like a duck and looks like a duck, it's a duck."
Duck Typing means you can pass two objects of completely different classes to the method and have it work because they both implement the same methods/attributes (or handles missing ones gracefully). This means that the method never cares about about what type it gets, just that whatever object you pass it has the attributes it expects to use.
In your case you want to pass an object sometimes and a string that can be used to look up said object other times. This has nothing to do with Duck Typing.
isinstance is the right way to solve this. In this case this is the clearest way to solve the problem, anything else is going to be more complicated, harder to understand have 0 benefits. You could use try/except on an attribute or hasattr, but that's likely to leave any future developers more confused than anything else. Duck Typing is great it replaces casting various subclasses around to match some particular function, but duck typing doesn't apply in this case.
In short. Just use isinstance. For your case it's the right (pythonic) way to do it.
I'm not sure that that is a terrible way of handling that, but if I wanted to do something similar, I would probably use hasattr:
def foo(bar):
if hasattr(bar,"pk"):
bar.pk
else:
# I include the str in case some other object with a __str__ happens
# to come through.
bar = Bar.objects.get(slug=str(bar))
This is another way which will help in other functions you want to do the same. I'll asume the model's name you are using is 'Item'.
def slug_resilient_decorator(class_type):
def slug_resilient_wrapper(obj):
if obj.has_attr('pk'):
return obj
else:
return class_type.objects.get(slug=obj)
return wrapper
#slug_resilient_decorator(Item)
def slug_resilient_detail_view(obj):
...