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.
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to