1.11M Members

if attribute exists: append; else: create

 
0
 

Which is smarter?

class HoldAttr(object): pass
a = HoldAttr

b = getattr(a, 'attrname', [])
b.append(1)
setattr(a, 'attrname', b)

# or

try:
    b.a.append(1)
except AttributeError:
    b.a = [1]

... or something else?

Trying to learn.

 
0
 

Something else:

class HoldAttr(object):
    pass

a = HoldAttr()

print(hasattr(a, 'myattr1'))   # False

# create the attribute externally
# unless the class uses __slots__
a.myattr1 = []

print(hasattr(a, 'myattr1'))   # True

# test it
a.myattr1.append(1)

print(a.myattr1)  # [1]
 
0
 

That doesn't quite get me there.
Let me give some more context.

import randint

class HoldAttr(object): pass

aname = [HoldAttr() for x in range(10000)]

for i in range(500):
    aindex = random.randint(0, 999)
    try:
        aname[aindex].foundat.append(i)
    except AttributeError:
        aname[aindex].foundat = [i]

Most instances in aname will have no 'foundat' attribute. Some instances in aname may be "found" more than once. Trying not to initialize a 'foundat' attribute for every instance in aname.

 
0
 

I suggest using a cached property

class HoldAttr(object):

    @cached_property
    def foundat(self):
        return []

    @property
    def was_found(self):
        return "foundat" in self.__dict__

if __name__ == "__main__":
    h = HoldAttr()
    for i in range(3):
        h.foundat.append(i)
    print(h.foundat)
    print(h.was_found)
    h = HoldAttr()
    print(h.was_found)

""" my output -->
[0, 1, 2]
True
False
"""

However, a more classical style makes your code more readable

class HoldAttr(object):
    foundat = None

    def add_found(self, at):
        if self.foundat is None:
            self.foundat = [at]
        else:
            self.foundat.append(at)

    def was_found(self):
        return self.foundat is not None

if __name__ == "__main__":
    h = HoldAttr()
    for i in range(3):
        h.add_found(i)
    print(h.foundat)
    print(h.was_found())
    h = HoldAttr()
    print(h.was_found())

Code with straightforward behavior is better.

 
1
 

The cached property is definatly the best suggestion. If not using that, I would get in the habit of using try: except in these situations. That is syntactially simple and very common, so others reading your code will be able to deduce your intent from the code.

You
This article has been dead for over six months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article