> On 23-Jun-2019, at 2:31 PM, Cameron Simpson <c...@cskk.id.au> wrote: > > On 23Jun2019 13:26, Arup Rakshit <a...@zeit.io> wrote: >> In the below code: >> >> @classmethod >> def find(self, id): >> if isinstance(id, list): >> rows = self.__table__().get_all(*id).run(self.__db__().conn) >> result = [] >> for row in rows: >> acategory = Category() >> acategory.__dict__.update(row) >> result.append(acategory) >> return result >> else: >> adict = self.__table__().get(id).run(self.__db__().conn) >> acategory = Category() >> acategory.__dict__.update(adict) >> return acategory >> >> I have 2 questions: >> >> 1. Is there any better way to create attributes in an object without using >> __dict__().update() or this is a correct approach? > > setattr() is the usual approach, but that sets a single attribute at a time. > If you have many then __dict__.update may be reasonable. > > You should bear in mind that not all objects have a __dict__. It is uncommon, > but if a class is defined with a __slots__ attribute then its instances have > fixed attribute names and there is no __dict__. Also some builtin types have > not __dict__. However, you likely know that the objects you are using have a > __dict__, so you're probably good. > > Also, __dict__ bypasses properties and descriptors. That might be important. > >> 2. Can we get the same result what for row in rows: block is producing >> without killing the readability ? > > Not obviously. It looks pretty direct to me. > > Unless the Category class can be made to accept an attribute map in its > __int__ method, then you might do some variable on: > > result = [ Category(row) for row in rows ] > > which is pretty readable. > > BTW, @classmethods receive the class as the first argument, not an instance. > So you'd normally write: > > @classmethod > def find(cls, id): > … >
What I know, is that first argument is reserved for the instance upon which it is called. It can be any name, so continued to use self. Yes these methods are class method intentionally. I am not aware of so far the naming rules of the first argument of a class or instance method. > and you would not have a self to use. is __table__ a class atribute or an > instance attribute? Yes __table__ class attribute defined in the BaseModel. > >> To see the context, here is my source code >> https://gitlab.com/aruprakshit/flask_awesome_recipes/blob/master/app/models/category.py > > Ah, so Category inherits from BaseModel. That means you can write your own > __init__. If it accepted an optional mapping (i.e. a dict or row) you could > put the .update inside __init__, supporting the list comprehension I suggest > above. Nice idea. I’ll try this. > > It looks like you've marks almost all the methods as @classmethods. Are you > sure about that? They all seem written to use self, and thus be instance > methods. > > Cheers, > Cameron Simpson <c...@cskk.id.au> Thanks, Arup Rakshit a...@zeit.io -- https://mail.python.org/mailman/listinfo/python-list