• Optional arguments in a class behave like class attributes.

    From Abderrahim Adrabi@21:1/5 to All on Sun Oct 16 11:48:45 2022
    Hi all,

    I tried to create a class with some optional arguments as always, but this
    time I used the default values to be lists, dictionaries, and object references.

    So, these default values behave like class attributes, here is a demo:

    # Using a list -----------------------------
    class GameOne:
    def __init__(self, games = []) -> None:
    self.games = games

    h = GameOne()
    h.games.append("List, the first round")

    g = GameOne()
    g.games.append("List, the second round")

    k = GameOne()
    print('Using a list', k.games)

    # Using a dictionary --------------------------
    class GameTwo:
    def __init__(self, games = {}) -> None:
    self.games = games

    h = GameTwo()
    h.games['1er'] = "Dictionary, the first round"

    g = GameTwo()
    g.games['2ed'] = "Dictionary, the second round"

    k = GameTwo()
    print('Using a dictionary', k.games)

    # Using an object ------------------------------
    class Bonus:
    def __init__(self) -> None:
    self.stages = []

    class GameThree:
    def __init__(self, bonus = Bonus()) -> None:
    self.bonus = bonus

    h = GameThree()
    h.bonus.stages.append('Object, the first round')

    g = GameThree()
    g.bonus.stages.append('Object, the second round')

    k = GameThree()
    print('Using an object', k.bonus.stages)

    # Results ----------------------------------------

    Using a list ['List, the first round', 'List, the second round']
    Using a dictionary {'1er': 'Dictionary, the first round', '2ed':
    'Dictionary, the second round'}
    Using an object ['Object, the first round', 'Object, the second round']

    # Used Python versions ---------------------------

    3.5.1 (default, Dec 9 2015, 14:41:32)
    [GCC 5.2.0]

    3.7.14 (default, Sep 8 2022, 00:06:44)
    [GCC 7.5.0]

    3.8.6 (default, Jan 29 2021, 17:38:16)
    [GCC 8.4.1 20200928 (Red Hat 8.4.1-1)]

    3.9.9 (main, Nov 20 2021, 21:30:06)
    [GCC 11.1.0]

    My question: Is this normal behavior?

    Thanks.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris Angelico@21:1/5 to abderrahim.adrabi@gmail.com on Tue Oct 18 01:57:13 2022
    On Tue, 18 Oct 2022 at 01:39, Abderrahim Adrabi
    <abderrahim.adrabi@gmail.com> wrote:
    So, these default values behave like class attributes, here is a demo:

    # Using a list -----------------------------
    class GameOne:
    def __init__(self, games = []) -> None:
    self.games = games


    This makes the default be a single list, the same list for all of
    them. If you want the default to be "construct a new list", you'll
    need something else:

    def __init__(self, games=None):
    if games is None: games = []

    There is an open proposal to allow this syntax, which would do what you want:

    def __init__(self, games=>[]):

    However, this is not part of any current version of Python.

    ChrisA

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Antoon Pardon@21:1/5 to All on Mon Oct 17 20:13:40 2022
    You can use the following decorator for what you probably want.

    def copy_defaults(func):
    """
    This decorator makes that defaults values are copied on a call.
    """

    signature = inspect.signature(func)
    parameter_items = list(signature.parameters.items())

    @wraps(func)
    def wrapper(*args, **kwds):
    newargs = list(args)
    tail_parameters = parameter_items[len(args):]
    for name, parameter in tail_parameters:
    try:
    newargs.append(kwds[name])
    del kwds[name]
    except KeyError:
    if parameter.default is not Parameter.empty:
    newargs.append(copy.deepcopy(parameter.default))
    else:
    break
    return func(*newargs, **kwds)

    return wrapper

    class GameOne:
    @copy_defaults
    def __init__(self, games = []) -> None:
    self.games = games

    # Results I got after using this decorator in your code

    Using a list []
    Using a dictionary {}
    Using an object []

    Op 16/10/2022 om 12:48 schreef Abderrahim Adrabi:
    Hi all,

    I tried to create a class with some optional arguments as always, but this time I used the default values to be lists, dictionaries, and object references.

    So, these default values behave like class attributes, here is a demo:

    # Using a list -----------------------------
    class GameOne:
    def __init__(self, games = []) -> None:
    self.games = games

    h = GameOne()
    h.games.append("List, the first round")

    g = GameOne()
    g.games.append("List, the second round")

    k = GameOne()
    print('Using a list', k.games)

    # Using a dictionary --------------------------
    class GameTwo:
    def __init__(self, games = {}) -> None:
    self.games = games

    h = GameTwo()
    h.games['1er'] = "Dictionary, the first round"

    g = GameTwo()
    g.games['2ed'] = "Dictionary, the second round"

    k = GameTwo()
    print('Using a dictionary', k.games)

    # Using an object ------------------------------
    class Bonus:
    def __init__(self) -> None:
    self.stages = []

    class GameThree:
    def __init__(self, bonus = Bonus()) -> None:
    self.bonus = bonus

    h = GameThree()
    h.bonus.stages.append('Object, the first round')

    g = GameThree()
    g.bonus.stages.append('Object, the second round')

    k = GameThree()
    print('Using an object', k.bonus.stages)

    # Results ----------------------------------------

    Using a list ['List, the first round', 'List, the second round']
    Using a dictionary {'1er': 'Dictionary, the first round', '2ed':
    'Dictionary, the second round'}
    Using an object ['Object, the first round', 'Object, the second round']

    # Used Python versions ---------------------------

    3.5.1 (default, Dec 9 2015, 14:41:32)
    [GCC 5.2.0]

    3.7.14 (default, Sep 8 2022, 00:06:44)
    [GCC 7.5.0]

    3.8.6 (default, Jan 29 2021, 17:38:16)
    [GCC 8.4.1 20200928 (Red Hat 8.4.1-1)]

    3.9.9 (main, Nov 20 2021, 21:30:06)
    [GCC 11.1.0]

    My question: Is this normal behavior?

    Thanks.

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