What are the drawbacks to using callbacks for satisfying dependencies? And, is this an anti-pattern? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Can modules have properties the same way that objects can?How to import a module given its name?What is a callback function?What does Ruby have that Python doesn't, and vice versa?What is a callback?What's the preferred way to implement a hook or callback in Python?Creating a singleton in PythonHow do I tell a Makefile which dependencies are satisfied by which targetC# Dependency injection side effect (two step initialization anti-pattern)?Not sure if I should use relative imports or add parent dir to sys.path

Weaponising the Grasp-at-a-Distance spell

What are the main differences between Stargate SG-1 cuts?

Where is the Next Backup Size entry on iOS 12?

What is the chair depicted in Cesare Maccari's 1889 painting "Cicerone denuncia Catilina"?

NERDTreeMenu Remapping

Flight departed from the gate 5 min before scheduled departure time. Refund options

Differences to CCompactSize and CVarInt

Delete free apps from library

What does it mean that physics no longer uses mechanical models to describe phenomena?

A proverb that is used to imply that you have unexpectedly faced a big problem

two integers one line calculator

Is there hard evidence that the grant peer review system performs significantly better than random?

How do living politicians protect their readily obtainable signatures from misuse?

Co-worker has annoying ringtone

Can two person see the same photon?

Can you force honesty by using the Speak with Dead and Zone of Truth spells together?

How can I prevent/balance waiting and turtling as a response to cooldown mechanics

As a dual citizen, my US passport will expire one day after traveling to the US. Will this work?

Is it dangerous to install hacking tools on my private linux machine?

AppleTVs create a chatty alternate WiFi network

A term for a woman complaining about things/begging in a cute/childish way

How can a team of shapeshifters communicate?

Printing attributes of selection in ArcPy?

What would you call this weird metallic apparatus that allows you to lift people?



What are the drawbacks to using callbacks for satisfying dependencies? And, is this an anti-pattern?



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!Can modules have properties the same way that objects can?How to import a module given its name?What is a callback function?What does Ruby have that Python doesn't, and vice versa?What is a callback?What's the preferred way to implement a hook or callback in Python?Creating a singleton in PythonHow do I tell a Makefile which dependencies are satisfied by which targetC# Dependency injection side effect (two step initialization anti-pattern)?Not sure if I should use relative imports or add parent dir to sys.path



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








0















I have two modules:



#module_a

def make_a(cb = None):

global a

a = 1 # It takes a very long time to make "a", so it is stored as a global in module_a.

if cb != None:

cb()


And,



#module_b

import module_a

def make_b():

global b

#In order to make "b", we need module_a.a, however there is no guarantee it has been made.
if 'a' not in dir(module_a):

module_a.make_a(make_b)

return

else:

b = module_a.a + 1

make_b()

print(b) # 2


In the above code, the function make_b in module_b makes something named b, which depends on something named a in module_a. In order to satisfy its dependency, it calls make_a with a callback to make_b. Once a is made, then make_b is called again and b is made.



This pattern makes sense to me, but I am wondering if this is a generally accepted approach to doing this or if it is an anti-pattern.



Is there a more canonical approach to satisfying such a dependency in Python i.e., the Pythonic way?










share|improve this question
























  • I would consider the use of global variables an anti-pattern, yes. The "canonical" way is to provide arguments to your functions and return values from them.

    – juanpa.arrivillaga
    Mar 8 at 23:12











  • I cannot do that because it takes a long time to make "a".

    – adpatter
    Mar 8 at 23:12











  • Sure you can. Global variables are not the usual way of implementing caching to begin with

    – juanpa.arrivillaga
    Mar 8 at 23:13











  • If I did that, then it would merely be a getter - I would still need for make_b to execute after a is made.

    – adpatter
    Mar 8 at 23:14







  • 1





    Your current approach looks like a leaky abstraction, because every client that wants to access a must include that ugly attribute-check and callback. A much cleaner approach would be to eliminate the callback and put the attribute-check in module_a. Clients should then call make_a, which would cache and return the required value. This would also eliminate the need for a mutable module attribute, which as others have noted, is also an anti-pattern in python.

    – ekhumoro
    Mar 8 at 23:58

















0















I have two modules:



#module_a

def make_a(cb = None):

global a

a = 1 # It takes a very long time to make "a", so it is stored as a global in module_a.

if cb != None:

cb()


And,



#module_b

import module_a

def make_b():

global b

#In order to make "b", we need module_a.a, however there is no guarantee it has been made.
if 'a' not in dir(module_a):

module_a.make_a(make_b)

return

else:

b = module_a.a + 1

make_b()

print(b) # 2


In the above code, the function make_b in module_b makes something named b, which depends on something named a in module_a. In order to satisfy its dependency, it calls make_a with a callback to make_b. Once a is made, then make_b is called again and b is made.



This pattern makes sense to me, but I am wondering if this is a generally accepted approach to doing this or if it is an anti-pattern.



Is there a more canonical approach to satisfying such a dependency in Python i.e., the Pythonic way?










share|improve this question
























  • I would consider the use of global variables an anti-pattern, yes. The "canonical" way is to provide arguments to your functions and return values from them.

    – juanpa.arrivillaga
    Mar 8 at 23:12











  • I cannot do that because it takes a long time to make "a".

    – adpatter
    Mar 8 at 23:12











  • Sure you can. Global variables are not the usual way of implementing caching to begin with

    – juanpa.arrivillaga
    Mar 8 at 23:13











  • If I did that, then it would merely be a getter - I would still need for make_b to execute after a is made.

    – adpatter
    Mar 8 at 23:14







  • 1





    Your current approach looks like a leaky abstraction, because every client that wants to access a must include that ugly attribute-check and callback. A much cleaner approach would be to eliminate the callback and put the attribute-check in module_a. Clients should then call make_a, which would cache and return the required value. This would also eliminate the need for a mutable module attribute, which as others have noted, is also an anti-pattern in python.

    – ekhumoro
    Mar 8 at 23:58













0












0








0








I have two modules:



#module_a

def make_a(cb = None):

global a

a = 1 # It takes a very long time to make "a", so it is stored as a global in module_a.

if cb != None:

cb()


And,



#module_b

import module_a

def make_b():

global b

#In order to make "b", we need module_a.a, however there is no guarantee it has been made.
if 'a' not in dir(module_a):

module_a.make_a(make_b)

return

else:

b = module_a.a + 1

make_b()

print(b) # 2


In the above code, the function make_b in module_b makes something named b, which depends on something named a in module_a. In order to satisfy its dependency, it calls make_a with a callback to make_b. Once a is made, then make_b is called again and b is made.



This pattern makes sense to me, but I am wondering if this is a generally accepted approach to doing this or if it is an anti-pattern.



Is there a more canonical approach to satisfying such a dependency in Python i.e., the Pythonic way?










share|improve this question
















I have two modules:



#module_a

def make_a(cb = None):

global a

a = 1 # It takes a very long time to make "a", so it is stored as a global in module_a.

if cb != None:

cb()


And,



#module_b

import module_a

def make_b():

global b

#In order to make "b", we need module_a.a, however there is no guarantee it has been made.
if 'a' not in dir(module_a):

module_a.make_a(make_b)

return

else:

b = module_a.a + 1

make_b()

print(b) # 2


In the above code, the function make_b in module_b makes something named b, which depends on something named a in module_a. In order to satisfy its dependency, it calls make_a with a callback to make_b. Once a is made, then make_b is called again and b is made.



This pattern makes sense to me, but I am wondering if this is a generally accepted approach to doing this or if it is an anti-pattern.



Is there a more canonical approach to satisfying such a dependency in Python i.e., the Pythonic way?







python callback dependencies






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 8 at 23:29







adpatter

















asked Mar 8 at 23:10









adpatteradpatter

8919




8919












  • I would consider the use of global variables an anti-pattern, yes. The "canonical" way is to provide arguments to your functions and return values from them.

    – juanpa.arrivillaga
    Mar 8 at 23:12











  • I cannot do that because it takes a long time to make "a".

    – adpatter
    Mar 8 at 23:12











  • Sure you can. Global variables are not the usual way of implementing caching to begin with

    – juanpa.arrivillaga
    Mar 8 at 23:13











  • If I did that, then it would merely be a getter - I would still need for make_b to execute after a is made.

    – adpatter
    Mar 8 at 23:14







  • 1





    Your current approach looks like a leaky abstraction, because every client that wants to access a must include that ugly attribute-check and callback. A much cleaner approach would be to eliminate the callback and put the attribute-check in module_a. Clients should then call make_a, which would cache and return the required value. This would also eliminate the need for a mutable module attribute, which as others have noted, is also an anti-pattern in python.

    – ekhumoro
    Mar 8 at 23:58

















  • I would consider the use of global variables an anti-pattern, yes. The "canonical" way is to provide arguments to your functions and return values from them.

    – juanpa.arrivillaga
    Mar 8 at 23:12











  • I cannot do that because it takes a long time to make "a".

    – adpatter
    Mar 8 at 23:12











  • Sure you can. Global variables are not the usual way of implementing caching to begin with

    – juanpa.arrivillaga
    Mar 8 at 23:13











  • If I did that, then it would merely be a getter - I would still need for make_b to execute after a is made.

    – adpatter
    Mar 8 at 23:14







  • 1





    Your current approach looks like a leaky abstraction, because every client that wants to access a must include that ugly attribute-check and callback. A much cleaner approach would be to eliminate the callback and put the attribute-check in module_a. Clients should then call make_a, which would cache and return the required value. This would also eliminate the need for a mutable module attribute, which as others have noted, is also an anti-pattern in python.

    – ekhumoro
    Mar 8 at 23:58
















I would consider the use of global variables an anti-pattern, yes. The "canonical" way is to provide arguments to your functions and return values from them.

– juanpa.arrivillaga
Mar 8 at 23:12





I would consider the use of global variables an anti-pattern, yes. The "canonical" way is to provide arguments to your functions and return values from them.

– juanpa.arrivillaga
Mar 8 at 23:12













I cannot do that because it takes a long time to make "a".

– adpatter
Mar 8 at 23:12





I cannot do that because it takes a long time to make "a".

– adpatter
Mar 8 at 23:12













Sure you can. Global variables are not the usual way of implementing caching to begin with

– juanpa.arrivillaga
Mar 8 at 23:13





Sure you can. Global variables are not the usual way of implementing caching to begin with

– juanpa.arrivillaga
Mar 8 at 23:13













If I did that, then it would merely be a getter - I would still need for make_b to execute after a is made.

– adpatter
Mar 8 at 23:14






If I did that, then it would merely be a getter - I would still need for make_b to execute after a is made.

– adpatter
Mar 8 at 23:14





1




1





Your current approach looks like a leaky abstraction, because every client that wants to access a must include that ugly attribute-check and callback. A much cleaner approach would be to eliminate the callback and put the attribute-check in module_a. Clients should then call make_a, which would cache and return the required value. This would also eliminate the need for a mutable module attribute, which as others have noted, is also an anti-pattern in python.

– ekhumoro
Mar 8 at 23:58





Your current approach looks like a leaky abstraction, because every client that wants to access a must include that ugly attribute-check and callback. A much cleaner approach would be to eliminate the callback and put the attribute-check in module_a. Clients should then call make_a, which would cache and return the required value. This would also eliminate the need for a mutable module attribute, which as others have noted, is also an anti-pattern in python.

– ekhumoro
Mar 8 at 23:58












1 Answer
1






active

oldest

votes


















1














To do this in a "Pythonic" way you should introduce an Observer pattern that emits an event once a is computed and b should subscribe to a in order to be called after a is finished.



Here you have an observer example






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',
    autoActivateHeartbeat: false,
    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%2f55072258%2fwhat-are-the-drawbacks-to-using-callbacks-for-satisfying-dependencies-and-is-t%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    To do this in a "Pythonic" way you should introduce an Observer pattern that emits an event once a is computed and b should subscribe to a in order to be called after a is finished.



    Here you have an observer example






    share|improve this answer





























      1














      To do this in a "Pythonic" way you should introduce an Observer pattern that emits an event once a is computed and b should subscribe to a in order to be called after a is finished.



      Here you have an observer example






      share|improve this answer



























        1












        1








        1







        To do this in a "Pythonic" way you should introduce an Observer pattern that emits an event once a is computed and b should subscribe to a in order to be called after a is finished.



        Here you have an observer example






        share|improve this answer















        To do this in a "Pythonic" way you should introduce an Observer pattern that emits an event once a is computed and b should subscribe to a in order to be called after a is finished.



        Here you have an observer example







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 8 at 23:20









        Robert Harvey

        150k35277422




        150k35277422










        answered Mar 8 at 23:16









        Pablo MartinezPablo Martinez

        3215




        3215





























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55072258%2fwhat-are-the-drawbacks-to-using-callbacks-for-satisfying-dependencies-and-is-t%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







            Popular posts from this blog

            1928 у кіно

            Захаров Федір Захарович

            Ель Греко