I have the following function:
def second(first, a):
# i want to return the results of first(a) in this function.
I just can't figure out how i can put values in (first(a)) without creating another function, or using lambda or any other modules? Any help is appreciated.
Maybe you could call the function first passing as parameter a, and then return the value it returned:
def second(first, a):
return first(a)
>>> def first(a, *args, **kwargs):
... print((a, args, kwargs))
...
>>> def second(func, a, *args, **kwargs):
... return func(a, *args, **kwargs)
...
>>> second(first, 'hello', 'world', do='something')
('hello', ('world',), {'do': 'something'})
>>> second(int, 15)
15
>>> second(range, 2, 5)
range(2, 5)
You can omit *args or **kwargs part if you know you don't need additional arguments or keyword arguments for your functions.
Related
I was trying to create a Generative Adverserial Network using PyTorch. I coded the discriminator block and printed the summary. After that, I moved to create Generator block. I defined forward() function and reshaped the input noise dimensions from (batch_size, noise_dim) to (batch_size, channel, height, width). While running the code for getting summary, the error popped saying 'NoneType' object is not callable. I searched stackoverflow and other places but my problem didn't resolved.
I first created a generator block function with the following code:
def get_gen_block(in_channels, out_channels, kernel_size, stride, final_block = False):
if final_block == True:
return nn.Sequential(
nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride),
nn.Tanh()
)
return nn.Sequential(
nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride),
nn.BatchNorm2d(out_channels),
nn.ReLU()
)
Then I defined a class for generator block to create several class and defined forward() function linke this:
class Generator(nn.Module):
def __init__(self, noise_dim):
super(Generator, self).__init__()
self.noise_dim = noise_dim
self.block_1 = get_gen_block(noise_dim, 256, (3, 3), 2)
self.block_2 = get_gen_block(256, 128, (4, 4), 1)
self.block_3 = get_gen_block(128, 64, (3, 3), 2)
self.block_4 = get_gen_block(64, 1, (4, 4), 2, final_block=True)
def forward(self, r_noise_vec):
x = r_noise_vec.view(-1, self.noise_dim, 1, 1)
x1 = self.block_1(x)
x2 = self.block_2(x1)
x3 = self.block_3(x2)
x4 = self.block_4(x3)
return x4
After this, when I was printing summary for the generator, this error occured pointing to the line 'x1 = self.block_1(x)' saying 'NoneType' object is not callable. Anyone please help me in resolving this issue.
Please check your get_gen_block function, looks like you missed else: branch or messed up the indentation and when final_block = False it returns None instead of
return nn.Sequential(
nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride),
nn.BatchNorm2d(out_channels),
nn.ReLU()
)
if cond:
return module1
return module2
Always returns module1 when condition is met, otherwise None.
I think you wanted this
if cond:
return module1
return module2
when condition is met return module1 otherwise module2. and now compare the indentation.
Say I have the following:
def foo(arg1, arg2, arg3 = default, *args, *kwargs*):
"""This function is really cool."""
return
How can I define a new function functionprinter(f) so that functionprinter(f) would print
foo(arg1, arg2, arg3 = default, *args, *kwargs*)
This function is really cool.
or something of that nature? I already know foo.__name__ and foo.__doc__ and have seen the inspect module, specifically here: Getting method parameter names in python but can't seem to string together everything, in particular having the default arguments print properly. I am using Python 3.4.1.
Yup! You can with the inspect module:
import inspect
def foo(arg1, arg2, arg3=None , *args, **kwargs):
"""This function is really cool."""
return
def functionprinter(f):
print("{}{}".format(f.__name__, inspect.signature(f)))
print(inspect.getdoc(f))
functionprinter(foo)
Prints:
foo(arg1, arg2, arg3=None, *args, **kwargs)
This function is really cool.
Note that I changed your default argument to None just for this demonstration because I didn't have the variable default defined.
You can use inspect.signature (to represents the call signature of a callable object and its return annotation.) and inspect.getdoc :
>>> print(inspect.signature(foo))
(arg1, arg2, arg3=3, *args, **kwargs)
>>> inspect.getdoc(foo)
'This function is really cool.'
>>> print ('\n'.join((foo.__name__+str(inspect.signature(foo)),inspect.getdoc(foo))))
foo(arg1, arg2, arg3='', *args, **kwargs)
This function is really cool.
In my tornado application initialization I am creating a session:
self.db = scoped_session(sessionmaker(bind=engine, query_cls=CustomQuery))
CustomQuery:
class CustomQuery(Query):
def __new__(cls, *args, **kwargs):
if args and hasattr(cls, "username"):
return Query(*args, **kwargs).filter_by(username="john")
else:
return Query(*args, **kwargs)
How can I pass some sort of parameter to the CustomQuery class, so that if a different username is passed it is filtered on that username?
update
Since one effect of these functions is to provide a way to use method chaining on methods that would not normally support it *, I'm considering calling them chain and copychain, respectively. This seems less than ideal though, since the would-be copychain is arguably a more fundamental concept, at least in terms of functional programming.
original
I'm calling it a boxer for now. The code is in Python, though the question is general:
def boxer(f):
"""Return a function g(o, *args, **keyargs) -> o
`g` calls `f` on `o` with the remaining arguments
and returns `o`.
>>> l = [2]
>>> def increment_list_element(l, i):
... l[0] += i
>>> adder = boxer(increment_list_element)
>>> adder(l, 2)
[4]
>>> def multiply_list_element(l, i):
... l[0] *= i
>>> multiplier = boxer(multiply_list_element)
>>> sum(multiplier(l, 6))
24
"""
def box(o, *args, **keyargs):
f(o, *args, **keyargs)
return o
return box
A similar concept copies the would-be assignee, and assigns to and returns the copy. This one is a "shadow_boxer":
from copy import deepcopy
def shadow_boxer(f):
"""Return a function g(o, *args, **keyargs) -> p
`g` deepcopies `o` as `p`,
executes `f` on `p` with the remaining arguments,
and returns `p`.
>>> l = [2]
>>> def increment_list_element(l, i):
... l[0] += i
>>> adder = shadow_boxer(increment_list_element)
>>> adder(l, 2)
[4]
>>> def multiply_list_element(l, i):
... l[0] *= i
>>> multiplier = shadow_boxer(multiply_list_element)
>>> sum(multiplier(l, 6))
12
"""
def shadow_box(o, *args, **keyargs):
p = deepcopy(o)
f(p, *args, **keyargs)
return p
return shadow_box
In addition, I'd like to find out about resources for learning more about these sorts of things — though I'm similarly unsure of a name for "these sorts of things". It does seem related to functional programming, although as I understand it, these technique would be unnecessary in a true functional language.
This is pretty much the same thing as Ruby's Object#tap. Don't know how you feel about the name, but that's what they call it.
What the boxer function returns is probably defined closure in some programming languages. If there is not already a function with this name, I would call the function closure.
I would like to write a bit of code that calls a function specified by a given argument. EG:
def caller(func):
return func()
However what I would also like to do is specify optional arguments to the 'caller' function so that 'caller' calls 'func' with the arguments specified (if any).
def caller(func, args):
# calls func with the arguments specified in args
Is there a simple, pythonic way to do this?
You can do this by using arbitrary argument lists and unpacking argument lists.
>>> def caller(func, *args, **kwargs):
... return func(*args, **kwargs)
...
>>> def hello(a, b, c):
... print a, b, c
...
>>> caller(hello, 1, b=5, c=7)
1 5 7
Not sure why you feel the need to do it, though.
This already exists as the apply function, though it is considered obsolete due to the new *args and **kwargs syntax.
>>> def foo(a,b,c): print a,b,c
>>> apply(foo, (1,2,3))
1 2 3
>>> apply(foo, (1,2), {'c':3}) # also accepts keyword args
However, the * and ** syntax is generally a better solution. The above is equivalent to:
>>> foo(*(1,2), **{'c':3})