How to make a function composer











up vote
15
down vote

favorite
2












I am trying to make a function that rounds other functions for my university degree . For example I would like to call the round_sqrt = round(sqrt)
and when i call the round_sqrt(5) it has to shows me 2 instead of 2.23606797749979. What I am trying is this:



def rounding(funct):
return round(funct)


but this doesn't work.



EDIT: The function should have only one parameter. For example
the start of the function should be



def rounding(func):


so in this function the funct function needs to be rounded.
so when I call rounding(abs)(3.2) it shows me 3.










share|improve this question




















  • 5




    You are looking for function composition. Mathematically, h = f ∘ g is defined as h(x) = f(g(x)). While it would be nice if Python a composition operator were available in Python, practical concerns require you to define the composed function yourself.
    – chepner
    Nov 7 at 17:20






  • 7




    playing with composition is one of the reasons I quickly fell in love with (then hated, then fell in love with, then hated, then...) Haskell.
    – Adam Smith
    Nov 7 at 17:25






  • 1




    Haskell is easy because everything fits into a theoretically sound mathematical framework. Haskell is hard because we are aren't use to conforming to said framework. :)
    – chepner
    Nov 7 at 17:35






  • 2




    You can either leave the question to help other people or delete it, but please don't just remove all the content.
    – Alex
    Nov 7 at 17:36






  • 1




    @AdamSmith Sounds like you were composing hate . love . hate . love
    – Mateen Ulhaq
    Nov 7 at 23:56















up vote
15
down vote

favorite
2












I am trying to make a function that rounds other functions for my university degree . For example I would like to call the round_sqrt = round(sqrt)
and when i call the round_sqrt(5) it has to shows me 2 instead of 2.23606797749979. What I am trying is this:



def rounding(funct):
return round(funct)


but this doesn't work.



EDIT: The function should have only one parameter. For example
the start of the function should be



def rounding(func):


so in this function the funct function needs to be rounded.
so when I call rounding(abs)(3.2) it shows me 3.










share|improve this question




















  • 5




    You are looking for function composition. Mathematically, h = f ∘ g is defined as h(x) = f(g(x)). While it would be nice if Python a composition operator were available in Python, practical concerns require you to define the composed function yourself.
    – chepner
    Nov 7 at 17:20






  • 7




    playing with composition is one of the reasons I quickly fell in love with (then hated, then fell in love with, then hated, then...) Haskell.
    – Adam Smith
    Nov 7 at 17:25






  • 1




    Haskell is easy because everything fits into a theoretically sound mathematical framework. Haskell is hard because we are aren't use to conforming to said framework. :)
    – chepner
    Nov 7 at 17:35






  • 2




    You can either leave the question to help other people or delete it, but please don't just remove all the content.
    – Alex
    Nov 7 at 17:36






  • 1




    @AdamSmith Sounds like you were composing hate . love . hate . love
    – Mateen Ulhaq
    Nov 7 at 23:56













up vote
15
down vote

favorite
2









up vote
15
down vote

favorite
2






2





I am trying to make a function that rounds other functions for my university degree . For example I would like to call the round_sqrt = round(sqrt)
and when i call the round_sqrt(5) it has to shows me 2 instead of 2.23606797749979. What I am trying is this:



def rounding(funct):
return round(funct)


but this doesn't work.



EDIT: The function should have only one parameter. For example
the start of the function should be



def rounding(func):


so in this function the funct function needs to be rounded.
so when I call rounding(abs)(3.2) it shows me 3.










share|improve this question















I am trying to make a function that rounds other functions for my university degree . For example I would like to call the round_sqrt = round(sqrt)
and when i call the round_sqrt(5) it has to shows me 2 instead of 2.23606797749979. What I am trying is this:



def rounding(funct):
return round(funct)


but this doesn't work.



EDIT: The function should have only one parameter. For example
the start of the function should be



def rounding(func):


so in this function the funct function needs to be rounded.
so when I call rounding(abs)(3.2) it shows me 3.







python python-3.x python-decorators function-composition






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 7 at 23:28









Alex

10.2k32354




10.2k32354










asked Nov 7 at 17:14









php kubrick

875




875








  • 5




    You are looking for function composition. Mathematically, h = f ∘ g is defined as h(x) = f(g(x)). While it would be nice if Python a composition operator were available in Python, practical concerns require you to define the composed function yourself.
    – chepner
    Nov 7 at 17:20






  • 7




    playing with composition is one of the reasons I quickly fell in love with (then hated, then fell in love with, then hated, then...) Haskell.
    – Adam Smith
    Nov 7 at 17:25






  • 1




    Haskell is easy because everything fits into a theoretically sound mathematical framework. Haskell is hard because we are aren't use to conforming to said framework. :)
    – chepner
    Nov 7 at 17:35






  • 2




    You can either leave the question to help other people or delete it, but please don't just remove all the content.
    – Alex
    Nov 7 at 17:36






  • 1




    @AdamSmith Sounds like you were composing hate . love . hate . love
    – Mateen Ulhaq
    Nov 7 at 23:56














  • 5




    You are looking for function composition. Mathematically, h = f ∘ g is defined as h(x) = f(g(x)). While it would be nice if Python a composition operator were available in Python, practical concerns require you to define the composed function yourself.
    – chepner
    Nov 7 at 17:20






  • 7




    playing with composition is one of the reasons I quickly fell in love with (then hated, then fell in love with, then hated, then...) Haskell.
    – Adam Smith
    Nov 7 at 17:25






  • 1




    Haskell is easy because everything fits into a theoretically sound mathematical framework. Haskell is hard because we are aren't use to conforming to said framework. :)
    – chepner
    Nov 7 at 17:35






  • 2




    You can either leave the question to help other people or delete it, but please don't just remove all the content.
    – Alex
    Nov 7 at 17:36






  • 1




    @AdamSmith Sounds like you were composing hate . love . hate . love
    – Mateen Ulhaq
    Nov 7 at 23:56








5




5




You are looking for function composition. Mathematically, h = f ∘ g is defined as h(x) = f(g(x)). While it would be nice if Python a composition operator were available in Python, practical concerns require you to define the composed function yourself.
– chepner
Nov 7 at 17:20




You are looking for function composition. Mathematically, h = f ∘ g is defined as h(x) = f(g(x)). While it would be nice if Python a composition operator were available in Python, practical concerns require you to define the composed function yourself.
– chepner
Nov 7 at 17:20




7




7




playing with composition is one of the reasons I quickly fell in love with (then hated, then fell in love with, then hated, then...) Haskell.
– Adam Smith
Nov 7 at 17:25




playing with composition is one of the reasons I quickly fell in love with (then hated, then fell in love with, then hated, then...) Haskell.
– Adam Smith
Nov 7 at 17:25




1




1




Haskell is easy because everything fits into a theoretically sound mathematical framework. Haskell is hard because we are aren't use to conforming to said framework. :)
– chepner
Nov 7 at 17:35




Haskell is easy because everything fits into a theoretically sound mathematical framework. Haskell is hard because we are aren't use to conforming to said framework. :)
– chepner
Nov 7 at 17:35




2




2




You can either leave the question to help other people or delete it, but please don't just remove all the content.
– Alex
Nov 7 at 17:36




You can either leave the question to help other people or delete it, but please don't just remove all the content.
– Alex
Nov 7 at 17:36




1




1




@AdamSmith Sounds like you were composing hate . love . hate . love
– Mateen Ulhaq
Nov 7 at 23:56




@AdamSmith Sounds like you were composing hate . love . hate . love
– Mateen Ulhaq
Nov 7 at 23:56












3 Answers
3






active

oldest

votes

















up vote
14
down vote



accepted










For your specific example, you can write



def round_sqrt(x):
return round(sqrt(x))


Alex's answer generalizes this; he defines a function that creates round_sqrt for you. If the function is already defined, you just pass it as an argument to rounder:



round_sqrt = rounder(sqrt)


Of course, you don't need to define round_sqrt if you don't want to. rounder(sqrt)(3.2) can be called directly, although it's far more efficient to safe the return value of rounder if you expect to use it multiple times, rather than redefining it each time.



Otherwise, the decorator syntax is just short for (using Alex's example)



def adder(x, y):
return x + y

adder = rounder(adder)




As I said in my comment, this is an example of implementing composition. Mathematically, composition is simple, because mathematical functions always take a single argument and return a single argument. As such, the composition of two functions f and g could always be defined simply as



def compose(f, g):
def h(x): # The name doesn't matter
return f(g(x))
return h


Then



round_sqrt = compose(round, sqrt)


(Ignoring all sorts of practical concerns around the implementation, Python could in theory even provide a Unicode operator for functions: round_sqrt = round ∘ sort. Explaining why this won't happen is beyond the scope of this answer.)



In Python, though, functions are far more complicated. They can take multiple arguments, they can accept arbitrary numbers of arguments and arbitrary keyword arguments, and while each technically returns a single value, that value can be a tuple which is thought of as multiple values or a dict. As a result, there may be many ways you might expect to pass the return value of g to a function f, more than can easily be accommodated in a simple compose function.






share|improve this answer























  • Shouldn't return f(g(z)) be return f(g(x))?
    – slider
    Nov 7 at 17:35










  • Yeah, I don't know where z came from.
    – chepner
    Nov 7 at 17:36










  • Wouldn't it be cleaner to use a lambda inside compose?
    – Eric Duminil
    Nov 8 at 8:08










  • I find def to be clearer when it's possible to use it.
    – chepner
    Nov 8 at 13:34


















up vote
27
down vote













You should check out closures:



def rounder(func):
def inner(*args, **kwargs):
return round(func(*args, **kwargs))
return inner


Then you can decorate functions using the @ character:



@rounder
def adder(x, y):
return x + y

print(adder(1.1, 2.2))


outputs 3



Supplementary:




  1. You can use functools.wraps in your closure so you don't lose information (e.g. docstring, function name) about the original function.

  2. There are a bunch of resources for learning about closures (e.g. 1, 2) and decorators (e.g. 1, 2) that you can find by Googling those terms.






share|improve this answer



















  • 13




    Hey look, a decorator!
    – Adam Smith
    Nov 7 at 17:18






  • 1




    I cant understand anything. The answer should be more easier I think
    – php kubrick
    Nov 7 at 17:21






  • 5




    @phpkubrick what? It's 3 lines of code and a function header? How much more simple would you like it? You mentioned you're in university -- you can understand this.
    – Adam Smith
    Nov 7 at 17:21








  • 1




    I cant understand the *args, **kwargs
    – php kubrick
    Nov 7 at 17:22






  • 5




    @phpkubrick I guess that's the next bit of research you should do then, because they're used all over the place in Python and are incredibly useful. stackoverflow.com/questions/36901/…
    – Adam Smith
    Nov 7 at 17:23


















up vote
5
down vote













Function composition isn't supported natively in Python. You can use a decorator as per @Alex's solution. You can define a new function explicitly as per @chepner's solution.



Or you can use a 3rd party library. For example, via toolz.compose:



from toolz import compose

def adder(x, y):
return x + y

round_adder = compose(round, adder)

round_adder(1.1, 2.2) # 3





share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53194500%2fhow-to-make-a-function-composer%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    14
    down vote



    accepted










    For your specific example, you can write



    def round_sqrt(x):
    return round(sqrt(x))


    Alex's answer generalizes this; he defines a function that creates round_sqrt for you. If the function is already defined, you just pass it as an argument to rounder:



    round_sqrt = rounder(sqrt)


    Of course, you don't need to define round_sqrt if you don't want to. rounder(sqrt)(3.2) can be called directly, although it's far more efficient to safe the return value of rounder if you expect to use it multiple times, rather than redefining it each time.



    Otherwise, the decorator syntax is just short for (using Alex's example)



    def adder(x, y):
    return x + y

    adder = rounder(adder)




    As I said in my comment, this is an example of implementing composition. Mathematically, composition is simple, because mathematical functions always take a single argument and return a single argument. As such, the composition of two functions f and g could always be defined simply as



    def compose(f, g):
    def h(x): # The name doesn't matter
    return f(g(x))
    return h


    Then



    round_sqrt = compose(round, sqrt)


    (Ignoring all sorts of practical concerns around the implementation, Python could in theory even provide a Unicode operator for functions: round_sqrt = round ∘ sort. Explaining why this won't happen is beyond the scope of this answer.)



    In Python, though, functions are far more complicated. They can take multiple arguments, they can accept arbitrary numbers of arguments and arbitrary keyword arguments, and while each technically returns a single value, that value can be a tuple which is thought of as multiple values or a dict. As a result, there may be many ways you might expect to pass the return value of g to a function f, more than can easily be accommodated in a simple compose function.






    share|improve this answer























    • Shouldn't return f(g(z)) be return f(g(x))?
      – slider
      Nov 7 at 17:35










    • Yeah, I don't know where z came from.
      – chepner
      Nov 7 at 17:36










    • Wouldn't it be cleaner to use a lambda inside compose?
      – Eric Duminil
      Nov 8 at 8:08










    • I find def to be clearer when it's possible to use it.
      – chepner
      Nov 8 at 13:34















    up vote
    14
    down vote



    accepted










    For your specific example, you can write



    def round_sqrt(x):
    return round(sqrt(x))


    Alex's answer generalizes this; he defines a function that creates round_sqrt for you. If the function is already defined, you just pass it as an argument to rounder:



    round_sqrt = rounder(sqrt)


    Of course, you don't need to define round_sqrt if you don't want to. rounder(sqrt)(3.2) can be called directly, although it's far more efficient to safe the return value of rounder if you expect to use it multiple times, rather than redefining it each time.



    Otherwise, the decorator syntax is just short for (using Alex's example)



    def adder(x, y):
    return x + y

    adder = rounder(adder)




    As I said in my comment, this is an example of implementing composition. Mathematically, composition is simple, because mathematical functions always take a single argument and return a single argument. As such, the composition of two functions f and g could always be defined simply as



    def compose(f, g):
    def h(x): # The name doesn't matter
    return f(g(x))
    return h


    Then



    round_sqrt = compose(round, sqrt)


    (Ignoring all sorts of practical concerns around the implementation, Python could in theory even provide a Unicode operator for functions: round_sqrt = round ∘ sort. Explaining why this won't happen is beyond the scope of this answer.)



    In Python, though, functions are far more complicated. They can take multiple arguments, they can accept arbitrary numbers of arguments and arbitrary keyword arguments, and while each technically returns a single value, that value can be a tuple which is thought of as multiple values or a dict. As a result, there may be many ways you might expect to pass the return value of g to a function f, more than can easily be accommodated in a simple compose function.






    share|improve this answer























    • Shouldn't return f(g(z)) be return f(g(x))?
      – slider
      Nov 7 at 17:35










    • Yeah, I don't know where z came from.
      – chepner
      Nov 7 at 17:36










    • Wouldn't it be cleaner to use a lambda inside compose?
      – Eric Duminil
      Nov 8 at 8:08










    • I find def to be clearer when it's possible to use it.
      – chepner
      Nov 8 at 13:34













    up vote
    14
    down vote



    accepted







    up vote
    14
    down vote



    accepted






    For your specific example, you can write



    def round_sqrt(x):
    return round(sqrt(x))


    Alex's answer generalizes this; he defines a function that creates round_sqrt for you. If the function is already defined, you just pass it as an argument to rounder:



    round_sqrt = rounder(sqrt)


    Of course, you don't need to define round_sqrt if you don't want to. rounder(sqrt)(3.2) can be called directly, although it's far more efficient to safe the return value of rounder if you expect to use it multiple times, rather than redefining it each time.



    Otherwise, the decorator syntax is just short for (using Alex's example)



    def adder(x, y):
    return x + y

    adder = rounder(adder)




    As I said in my comment, this is an example of implementing composition. Mathematically, composition is simple, because mathematical functions always take a single argument and return a single argument. As such, the composition of two functions f and g could always be defined simply as



    def compose(f, g):
    def h(x): # The name doesn't matter
    return f(g(x))
    return h


    Then



    round_sqrt = compose(round, sqrt)


    (Ignoring all sorts of practical concerns around the implementation, Python could in theory even provide a Unicode operator for functions: round_sqrt = round ∘ sort. Explaining why this won't happen is beyond the scope of this answer.)



    In Python, though, functions are far more complicated. They can take multiple arguments, they can accept arbitrary numbers of arguments and arbitrary keyword arguments, and while each technically returns a single value, that value can be a tuple which is thought of as multiple values or a dict. As a result, there may be many ways you might expect to pass the return value of g to a function f, more than can easily be accommodated in a simple compose function.






    share|improve this answer














    For your specific example, you can write



    def round_sqrt(x):
    return round(sqrt(x))


    Alex's answer generalizes this; he defines a function that creates round_sqrt for you. If the function is already defined, you just pass it as an argument to rounder:



    round_sqrt = rounder(sqrt)


    Of course, you don't need to define round_sqrt if you don't want to. rounder(sqrt)(3.2) can be called directly, although it's far more efficient to safe the return value of rounder if you expect to use it multiple times, rather than redefining it each time.



    Otherwise, the decorator syntax is just short for (using Alex's example)



    def adder(x, y):
    return x + y

    adder = rounder(adder)




    As I said in my comment, this is an example of implementing composition. Mathematically, composition is simple, because mathematical functions always take a single argument and return a single argument. As such, the composition of two functions f and g could always be defined simply as



    def compose(f, g):
    def h(x): # The name doesn't matter
    return f(g(x))
    return h


    Then



    round_sqrt = compose(round, sqrt)


    (Ignoring all sorts of practical concerns around the implementation, Python could in theory even provide a Unicode operator for functions: round_sqrt = round ∘ sort. Explaining why this won't happen is beyond the scope of this answer.)



    In Python, though, functions are far more complicated. They can take multiple arguments, they can accept arbitrary numbers of arguments and arbitrary keyword arguments, and while each technically returns a single value, that value can be a tuple which is thought of as multiple values or a dict. As a result, there may be many ways you might expect to pass the return value of g to a function f, more than can easily be accommodated in a simple compose function.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 7 at 17:36

























    answered Nov 7 at 17:24









    chepner

    239k29227319




    239k29227319












    • Shouldn't return f(g(z)) be return f(g(x))?
      – slider
      Nov 7 at 17:35










    • Yeah, I don't know where z came from.
      – chepner
      Nov 7 at 17:36










    • Wouldn't it be cleaner to use a lambda inside compose?
      – Eric Duminil
      Nov 8 at 8:08










    • I find def to be clearer when it's possible to use it.
      – chepner
      Nov 8 at 13:34


















    • Shouldn't return f(g(z)) be return f(g(x))?
      – slider
      Nov 7 at 17:35










    • Yeah, I don't know where z came from.
      – chepner
      Nov 7 at 17:36










    • Wouldn't it be cleaner to use a lambda inside compose?
      – Eric Duminil
      Nov 8 at 8:08










    • I find def to be clearer when it's possible to use it.
      – chepner
      Nov 8 at 13:34
















    Shouldn't return f(g(z)) be return f(g(x))?
    – slider
    Nov 7 at 17:35




    Shouldn't return f(g(z)) be return f(g(x))?
    – slider
    Nov 7 at 17:35












    Yeah, I don't know where z came from.
    – chepner
    Nov 7 at 17:36




    Yeah, I don't know where z came from.
    – chepner
    Nov 7 at 17:36












    Wouldn't it be cleaner to use a lambda inside compose?
    – Eric Duminil
    Nov 8 at 8:08




    Wouldn't it be cleaner to use a lambda inside compose?
    – Eric Duminil
    Nov 8 at 8:08












    I find def to be clearer when it's possible to use it.
    – chepner
    Nov 8 at 13:34




    I find def to be clearer when it's possible to use it.
    – chepner
    Nov 8 at 13:34












    up vote
    27
    down vote













    You should check out closures:



    def rounder(func):
    def inner(*args, **kwargs):
    return round(func(*args, **kwargs))
    return inner


    Then you can decorate functions using the @ character:



    @rounder
    def adder(x, y):
    return x + y

    print(adder(1.1, 2.2))


    outputs 3



    Supplementary:




    1. You can use functools.wraps in your closure so you don't lose information (e.g. docstring, function name) about the original function.

    2. There are a bunch of resources for learning about closures (e.g. 1, 2) and decorators (e.g. 1, 2) that you can find by Googling those terms.






    share|improve this answer



















    • 13




      Hey look, a decorator!
      – Adam Smith
      Nov 7 at 17:18






    • 1




      I cant understand anything. The answer should be more easier I think
      – php kubrick
      Nov 7 at 17:21






    • 5




      @phpkubrick what? It's 3 lines of code and a function header? How much more simple would you like it? You mentioned you're in university -- you can understand this.
      – Adam Smith
      Nov 7 at 17:21








    • 1




      I cant understand the *args, **kwargs
      – php kubrick
      Nov 7 at 17:22






    • 5




      @phpkubrick I guess that's the next bit of research you should do then, because they're used all over the place in Python and are incredibly useful. stackoverflow.com/questions/36901/…
      – Adam Smith
      Nov 7 at 17:23















    up vote
    27
    down vote













    You should check out closures:



    def rounder(func):
    def inner(*args, **kwargs):
    return round(func(*args, **kwargs))
    return inner


    Then you can decorate functions using the @ character:



    @rounder
    def adder(x, y):
    return x + y

    print(adder(1.1, 2.2))


    outputs 3



    Supplementary:




    1. You can use functools.wraps in your closure so you don't lose information (e.g. docstring, function name) about the original function.

    2. There are a bunch of resources for learning about closures (e.g. 1, 2) and decorators (e.g. 1, 2) that you can find by Googling those terms.






    share|improve this answer



















    • 13




      Hey look, a decorator!
      – Adam Smith
      Nov 7 at 17:18






    • 1




      I cant understand anything. The answer should be more easier I think
      – php kubrick
      Nov 7 at 17:21






    • 5




      @phpkubrick what? It's 3 lines of code and a function header? How much more simple would you like it? You mentioned you're in university -- you can understand this.
      – Adam Smith
      Nov 7 at 17:21








    • 1




      I cant understand the *args, **kwargs
      – php kubrick
      Nov 7 at 17:22






    • 5




      @phpkubrick I guess that's the next bit of research you should do then, because they're used all over the place in Python and are incredibly useful. stackoverflow.com/questions/36901/…
      – Adam Smith
      Nov 7 at 17:23













    up vote
    27
    down vote










    up vote
    27
    down vote









    You should check out closures:



    def rounder(func):
    def inner(*args, **kwargs):
    return round(func(*args, **kwargs))
    return inner


    Then you can decorate functions using the @ character:



    @rounder
    def adder(x, y):
    return x + y

    print(adder(1.1, 2.2))


    outputs 3



    Supplementary:




    1. You can use functools.wraps in your closure so you don't lose information (e.g. docstring, function name) about the original function.

    2. There are a bunch of resources for learning about closures (e.g. 1, 2) and decorators (e.g. 1, 2) that you can find by Googling those terms.






    share|improve this answer














    You should check out closures:



    def rounder(func):
    def inner(*args, **kwargs):
    return round(func(*args, **kwargs))
    return inner


    Then you can decorate functions using the @ character:



    @rounder
    def adder(x, y):
    return x + y

    print(adder(1.1, 2.2))


    outputs 3



    Supplementary:




    1. You can use functools.wraps in your closure so you don't lose information (e.g. docstring, function name) about the original function.

    2. There are a bunch of resources for learning about closures (e.g. 1, 2) and decorators (e.g. 1, 2) that you can find by Googling those terms.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 7 at 17:26

























    answered Nov 7 at 17:16









    Alex

    10.2k32354




    10.2k32354








    • 13




      Hey look, a decorator!
      – Adam Smith
      Nov 7 at 17:18






    • 1




      I cant understand anything. The answer should be more easier I think
      – php kubrick
      Nov 7 at 17:21






    • 5




      @phpkubrick what? It's 3 lines of code and a function header? How much more simple would you like it? You mentioned you're in university -- you can understand this.
      – Adam Smith
      Nov 7 at 17:21








    • 1




      I cant understand the *args, **kwargs
      – php kubrick
      Nov 7 at 17:22






    • 5




      @phpkubrick I guess that's the next bit of research you should do then, because they're used all over the place in Python and are incredibly useful. stackoverflow.com/questions/36901/…
      – Adam Smith
      Nov 7 at 17:23














    • 13




      Hey look, a decorator!
      – Adam Smith
      Nov 7 at 17:18






    • 1




      I cant understand anything. The answer should be more easier I think
      – php kubrick
      Nov 7 at 17:21






    • 5




      @phpkubrick what? It's 3 lines of code and a function header? How much more simple would you like it? You mentioned you're in university -- you can understand this.
      – Adam Smith
      Nov 7 at 17:21








    • 1




      I cant understand the *args, **kwargs
      – php kubrick
      Nov 7 at 17:22






    • 5




      @phpkubrick I guess that's the next bit of research you should do then, because they're used all over the place in Python and are incredibly useful. stackoverflow.com/questions/36901/…
      – Adam Smith
      Nov 7 at 17:23








    13




    13




    Hey look, a decorator!
    – Adam Smith
    Nov 7 at 17:18




    Hey look, a decorator!
    – Adam Smith
    Nov 7 at 17:18




    1




    1




    I cant understand anything. The answer should be more easier I think
    – php kubrick
    Nov 7 at 17:21




    I cant understand anything. The answer should be more easier I think
    – php kubrick
    Nov 7 at 17:21




    5




    5




    @phpkubrick what? It's 3 lines of code and a function header? How much more simple would you like it? You mentioned you're in university -- you can understand this.
    – Adam Smith
    Nov 7 at 17:21






    @phpkubrick what? It's 3 lines of code and a function header? How much more simple would you like it? You mentioned you're in university -- you can understand this.
    – Adam Smith
    Nov 7 at 17:21






    1




    1




    I cant understand the *args, **kwargs
    – php kubrick
    Nov 7 at 17:22




    I cant understand the *args, **kwargs
    – php kubrick
    Nov 7 at 17:22




    5




    5




    @phpkubrick I guess that's the next bit of research you should do then, because they're used all over the place in Python and are incredibly useful. stackoverflow.com/questions/36901/…
    – Adam Smith
    Nov 7 at 17:23




    @phpkubrick I guess that's the next bit of research you should do then, because they're used all over the place in Python and are incredibly useful. stackoverflow.com/questions/36901/…
    – Adam Smith
    Nov 7 at 17:23










    up vote
    5
    down vote













    Function composition isn't supported natively in Python. You can use a decorator as per @Alex's solution. You can define a new function explicitly as per @chepner's solution.



    Or you can use a 3rd party library. For example, via toolz.compose:



    from toolz import compose

    def adder(x, y):
    return x + y

    round_adder = compose(round, adder)

    round_adder(1.1, 2.2) # 3





    share|improve this answer

























      up vote
      5
      down vote













      Function composition isn't supported natively in Python. You can use a decorator as per @Alex's solution. You can define a new function explicitly as per @chepner's solution.



      Or you can use a 3rd party library. For example, via toolz.compose:



      from toolz import compose

      def adder(x, y):
      return x + y

      round_adder = compose(round, adder)

      round_adder(1.1, 2.2) # 3





      share|improve this answer























        up vote
        5
        down vote










        up vote
        5
        down vote









        Function composition isn't supported natively in Python. You can use a decorator as per @Alex's solution. You can define a new function explicitly as per @chepner's solution.



        Or you can use a 3rd party library. For example, via toolz.compose:



        from toolz import compose

        def adder(x, y):
        return x + y

        round_adder = compose(round, adder)

        round_adder(1.1, 2.2) # 3





        share|improve this answer












        Function composition isn't supported natively in Python. You can use a decorator as per @Alex's solution. You can define a new function explicitly as per @chepner's solution.



        Or you can use a 3rd party library. For example, via toolz.compose:



        from toolz import compose

        def adder(x, y):
        return x + y

        round_adder = compose(round, adder)

        round_adder(1.1, 2.2) # 3






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 7 at 17:24









        jpp

        83.9k194897




        83.9k194897






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53194500%2fhow-to-make-a-function-composer%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Academy of Television Arts & Sciences

            L'Équipe

            1995 France bombings