Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialChuck Todd
8,295 PointsINIT function allows user to override Weapon logic
Trying to understand best practices.
The weapon selection is supposed to be controlled by the get_weapon() method, but since that input is followed by the processing of the KWARGS argument the user can bypass this logic.
Ex: Slimy = Character(weapon="hammer')
In this case the selection logic will always be overridden by the value set in the instantiation call.
To best handle this should we check for the specific key and excluding any change that field:
def __init__(self, **kwargs):
self.name = input("Name: ")
self.weapon = self.get_weapon()
for key, value in kwargs.items():
if key != 'weapon':
setattr(self, key, value)
Appreciate all your work in this training.
2 Answers
Kenneth Love
Treehouse Guest TeacherYou typically won't assign explicit attributes from **kwargs
, though. Consider this:
def __init__(self, name, weapon, **kwargs):
self.name = name
self.weapon = weapon
for key, value in kwargs.items():
setattr(self, key, value)
There's no way for **kwargs
to have name
or weapon
in it.
Chris Freeman
Treehouse Moderator 68,427 PointsYes, that's the basic idea. If you wish more restrictive access to setting the weapon attribute, the filtering out the case works. Restricts can be define to be exclusionary or inclusive:
ALLOWED_ATTRIBUTES = ["sound", "max_hit_points", "min_hit_points"]
def __init__(self, **kwargs):
self.name = input("Name: ")
self.weapon = self.get_weapon()
for key, value in kwargs.items():
if key in ALLOWED_ATTRIBUTES:
setattr(self, key, value)
I've found using **kwargs
can make testing harder and error injection harder to prevent. It does have it's uses when you need to accept an argument that is used by the parent class init through super().__init__()
. YMMV.