0

I'm trying to solve a codewars problem that I'm not sure has a simple implementation in python. I want to dynamically create a class-method attribute simply by referencing it before it exists. It sounds so counter intuitive. How do you initialize a property inside the method when that property doesn't already exist and without setting a value to it from outside?

class Thing:
   def __init__(self, name):
      self.name = name

   @property
   def is_a(self):
      setattr(self.is_a,"is_a_{}".format(???),True)

john = Thing("John")
john.is_a.man
print(john.is_a_man) # this is directly from the cw test

Without setting it first (i.e. john.is_a.man = True), I don't see how this is possible. Not that using a try/except would be a good strategy, but I can't even figure out how to catch a reference to a non-existent attribute so I can create it in the handler. Any guidance on this would be appreciated. Or if it's simply not possible with Python, that would be good to know.

https://www.codewars.com/kata/5571d9fc11526780a000011a

dbconfession
  • 1,147
  • 2
  • 23
  • 36

1 Answers1

1

What the CodeWars thing wants is doable, but it's too much magic for too little benefit and a confusing interface, especially the later parts.

class IsA(object):
    def __init__(self, parent):
        self.parent = parent
    def __getattr__(self, name):
        setattr(self.parent, 'is_a_'+name, True)

class Thing(object):
    def __init__(self, name):
        self.name = name
        self.is_a = IsA(self)

The thing.is_a access doesn't need to do anything special; it's the thing.is_a.whatever access that does the magic, so thing.is_a needs to evaluate to an object with a hook for setting attributes on thing. We implement a Thing's is_a as an object whose __getattr__ sets the appropriate attribute of its parent.

user2357112
  • 260,549
  • 28
  • 431
  • 505