• Passing info to function used in re.sub

    From =?utf-8?q?Jan_Erik_Mostr=C3=B6m?=@21:1/5 to All on Sun Sep 3 18:10:29 2023
    I'm looking for some advice for how to write this in a clean way

    I want to replace some text using a regex-pattern, but before creating replacement text I need to some file checking/copying etc. My code right now look something like this:

    def fix_stuff(m):
    # Do various things that involves for info
    # that what's available in m
    replacement_text = m.group(1) + global_var1 + global_var2
    return replacement_text

    and the call comes here

    global_var1 = "bla bla"
    global_var2 = "pff"

    new_text = re.sub(im_pattern,fix_stuff,md_text)


    The "problem" is that I've currently written some code that works but it uses global variables ... and I don't like global variables. I assume there is a better way to write this, but how?

    = jem

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to lists@mostrom.pp.se on Sun Sep 3 16:53:02 2023
    =?utf-8?q?Jan_Erik_Mostr=C3=B6m?= <lists@mostrom.pp.se> writes:
    def fix_stuff(m):
    # that what's available in m
    replacement_text = m.group(1) + global_var1 + global_var2
    return replacement_text
    ...
    new_text = re.sub(im_pattern,fix_stuff,md_text)

    You can use a closure:

    import re

    def make_replace( was_global_1, was_global_2 ):
    def replace( matcher ):
    return matcher.group( 1 )+ was_global_1 + was_global_2
    return replace

    replace = make_replace( "a", "b" )

    print( re.sub( r'(.)', replace, 'x' ))

    . Note how I wrote code one can actually execute.
    You could have done this too!

    Or, partial application:

    import functools
    import re

    def replace( was_global_1, was_global_2, matcher ):
    return matcher.group( 1 )+ was_global_1 + was_global_2

    print( re.sub( r'(.)', functools.partial( replace, 'a', 'b' ), 'x' ))

    .

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From MRAB@21:1/5 to All on Sun Sep 3 18:13:10 2023
    On 2023-09-03 17:10, Jan Erik Moström via Python-list wrote:
    I'm looking for some advice for how to write this in a clean way

    I want to replace some text using a regex-pattern, but before creating replacement text I need to some file checking/copying etc. My code right now look something like this:

    def fix_stuff(m):
    # Do various things that involves for info
    # that what's available in m
    replacement_text = m.group(1) + global_var1 + global_var2
    return replacement_text

    and the call comes here

    global_var1 = "bla bla"
    global_var2 = "pff"

    new_text = re.sub(im_pattern,fix_stuff,md_text)


    The "problem" is that I've currently written some code that works but it uses global variables ... and I don't like global variables. I assume there is a better way to write this, but how?

    You could use pass an anonymous function (a lambda) to re.sub:

    def fix_stuff(m, var1, var2):
    # Do various things that involves for info
    # that what's available in m
    replacement_text = m.group(1) + var1 + var2
    return replacement_text

    global_var1 = "bla bla"
    global_var2 = "pff"

    new_text = re.sub(im_pattern, lambda m, var1=global_var1, var2=global_var2: fix_stuff(m, var1, var2), md_text)

    Or, if you prefer a named function, define one just before the re.sub:

    def fix_stuff(m, var1, var2):
    # Do various things that involves for info
    # that what's available in m
    replacement_text = m.group(1) + var1 + var2
    return replacement_text

    global_var1 = "bla bla"
    global_var2 = "pff"

    def fix_it(m, var1=global_var1, var2=global_var2):
    return fix_stuff(m, var1, var2)

    new_text = re.sub(im_pattern, fix_it, md_text)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?utf-8?q?Jan_Erik_Mostr=C3=B6m?=@21:1/5 to MRAB via Python-list on Sun Sep 3 19:58:17 2023
    On 3 Sep 2023, at 19:13, MRAB via Python-list wrote:

    You could use pass an anonymous function (a lambda) to re.sub:

    Of course !! Thanks.

    = jem

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to All on Sun Sep 3 18:20:43 2023
    On 9/3/2023 12:10 PM, Jan Erik Moström via Python-list wrote:
    I'm looking for some advice for how to write this in a clean way

    I want to replace some text using a regex-pattern, but before creating replacement text I need to some file checking/copying etc. My code right now look something like this:

    def fix_stuff(m):
    # Do various things that involves for info
    # that what's available in m
    replacement_text = m.group(1) + global_var1 + global_var2
    return replacement_text

    and the call comes here

    global_var1 = "bla bla"
    global_var2 = "pff"

    new_text = re.sub(im_pattern,fix_stuff,md_text)


    The "problem" is that I've currently written some code that works but it uses global variables ... and I don't like global variables. I assume there is a better way to write this, but how?

    = jem

    There are two things to keep in mind here, I think. First, in Python a "global" variable is really module-level, so variables specific to one
    module seem fine and are common practice.

    Second, the way you have written this example, it looks like these
    module-level "variables" are in effect constants. In other words, they
    are just shorthand for specific declared quantities. If this is so,
    then it makes even more sense to define them as module-level objects in
    the module that needs to use them.

    If you still don't want to use them as "global" in your module, then
    define them in a separate module and import them from that module.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter J. Holzer@21:1/5 to All on Mon Sep 4 21:00:02 2023
    On 2023-09-03 18:10:29 +0200, Jan Erik Moström via Python-list wrote:
    I want to replace some text using a regex-pattern, but before creating replacement text I need to some file checking/copying etc. My code
    right now look something like this:

    def fix_stuff(m):
    # Do various things that involves for info
    # that what's available in m
    replacement_text = m.group(1) + global_var1 + global_var2
    return replacement_text

    and the call comes here

    global_var1 = "bla bla"
    global_var2 = "pff"

    new_text = re.sub(im_pattern,fix_stuff,md_text)


    The "problem" is that I've currently written some code that works but
    it uses global variables ... and I don't like global variables. I
    assume there is a better way to write this, but how?

    If you use fix_stuff only inside one other function, you could make it
    local to that function so that it will capture the local variables of
    the outer function:

    import re

    def demo():

    local_var1 = "bla bla"
    local_var2 = "pff"

    def fix_stuff(m):
    # Do various things that involves for info
    # that what's available in m
    replacement_text = m.group(1) + local_var1 + local_var2
    return replacement_text

    for md_text in ( "aardvark", "barbapapa", "ba ba ba ba barbara ann"):
    new_text = re.sub(r"(a+).*?(b+)", fix_stuff, md_text)
    print(md_text, new_text)

    demo()

    hp

    --
    _ | Peter J. Holzer | Story must make more sense than reality.
    |_|_) | |
    | | | hjp@hjp.at | -- Charles Stross, "Creative writing
    __/ | http://www.hjp.at/ | challenge!"

    -----BEGIN PGP SIGNATURE-----

    iQIzBAABCgAdFiEETtJbRjyPwVTYGJ5k8g5IURL+KF0FAmT2KS0ACgkQ8g5IURL+ KF3Iqg//Ve3cB1xcR9BqqbDmZiELFvAeOZT+yHU8NOWpQZmt6+fM1fjfokyx0O7Z QrtKmqoWZImtRvbHoXY5f9yKyHq+6fN+DiVAjHr/GHycNkmaCzxMJO2WbJVq62Wi 4BbDYUsWDe89RcI7fy1FGqm0hCy6OVlvLIwbPoZwHduV/enyDNMSq3xWMPsC19PB xILwvYSZfVcQHloONWxvU5KDDUggMPH6c3bRNh4E2XV/K46D6uNT55ecMntPjCVT 0V9iKgrUakgTgA9o4sJrlFQTzifzVRmTflszEckHi1xbl8P+a7EMEGvD5fshix2u tgGSRdSHScoVk2sj1+2g6r2cauk7PTAw2+Lijx09Q6ziSzXS23tvuaISgq8g+Gvo BzAjGydVlveyV7N635nTgx4vqtZbKoS5lgQFXyq/GiDKVxYehefyupF9gxFnrBOk Df851NOo+gWs+SL2LxWYIFIh26aqA94GKhb98S6zPUi41ntpkNgb6f5KF6iJD4il Bt4+16sXsYxZxqkRk2N+HSp6Aq2W8Mw6BFFPiWV1qfkSku30k+Vq8js6imJTg/cA C32njm8IRNa9/LW2a/Axp9KaA02kcIu2jRbPfOvUB7/Dc80JXRlgK5pdc1VEV02D 6Ucl7nWxhwyp+MKCjGqjRrVdoSzrx2VSliZj7n7
  • From Dieter Maurer@21:1/5 to All on Mon Sep 4 21:37:30 2023
    Jan Erik Moström wrote at 2023-9-3 18:10 +0200:
    I'm looking for some advice for how to write this in a clean way
    ...
    The "problem" is that I've currently written some code that works but it uses global variables ... and I don't like global variables. I assume there is a better way to write this, but how?

    You could define a class with a `__call__` method
    and use an instance of the class as replacement.
    The class and/or instance can provide all relevant information via
    attributes.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?utf-8?q?Jan_Erik_Mostr=C3=B6m?=@21:1/5 to All on Tue Sep 5 10:05:11 2023
    On 3 Sep 2023, at 18:10, Jan Erik Moström via Python-list wrote:

    I'm looking for some advice for how to write this in a clean way

    Thanks for all the suggestion, I realize that I haven't written Python code in a while. I should have remembered this myself !!! Thanks for reminding me.

    = jem

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)