python - Use cases for property vs. descriptor vs. __getattribute__ -


the question refers which 1 preferable used in use case, not technical background.

in python, can control access of attributes via property, descriptor, or magic methods. 1 pythonic in use case? of them seem have same effect (see examples below).

i looking answer like:

  • property: should used in case of …
  • descriptor: in case of … should used instead of property.
  • magic method: use if ….

example

a use case attribute might not able set in __init__ method, example because object not present in database yet, @ later time. each time attribute accessed, should tried set , returned.

as example works copy&paste in python shell, there class wants present attribute second time asked it. so, 1 best way, or there different situations 1 of them preferable? here 3 ways implement it:

with property::

class contactbook(object):     intents = 0      def __init__(self):         self.__first_person = none      def get_first_person(self):         contactbook.intents += 1         if self.__first_person none:             if contactbook.intents > 1:                 value = 'mr. first'                 self.__first_person = value             else:                 return none         return self.__first_person      def set_first_person(self, value):         self.__first_person = value      first_person = property(get_first_person, set_first_person) 

with __getattribute__::

class contactbook(object):     intents = 0      def __init__(self):         self.first_person = none      def __getattribute__(self, name):         if name == 'first_person' \                 , object.__getattribute__(self, name) none:             contactbook.intents += 1             if contactbook.intents > 1:                 value = 'mr. first'                 self.first_person = value             else:                 value = none         else:             value = object.__getattribute__(self, name)         return value 

descriptor::

class firstperson(object):     def __init__(self, value=none):         self.value = none      def __get__(self, instance, owner):         if self.value none:             contactbook.intents += 1             if contactbook.intents > 1:                 self.value = 'mr. first'             else:                 return none         return self.value   class contactbook(object):     intents = 0     first_person = firstperson() 

each 1 of has behavior::

book = contactbook() print(book.first_person) # >>none print(book.first_person) # >>mr. first 

basically, use simplest 1 can. speaking, order of complexity/heavy-duty-ness goes: regular attribute, property, __getattr__, __getattribute__/descriptor. (__getattribute__ , custom descriptors both things won't need often.) leads simple rules of thumb:

  • don't use property if normal attribute work.
  • don't write own descriptor if property work.
  • don't use __getattr__ if property work.
  • don't use __getattribute__ if __getattr__ work.

stated bit more specifically: use property customize handling of 1 or small set of attributes; use __getattr__ customize handling of attributes, or except small set; use __getattribute__ if hoping use __getattr__ doesn't quite work; write own descriptor class if doing complicated.

you use property when have 1 or small set of attributes getting/setting want hook into. is, want things obj.prop , obj.prop = 2 secretly call function write customize happens.

you use __getattr__ when want many attributes don't want define them individually, rather want customize whole attribute-access process whole. in other words, instead of hooking obj.prop1, , obj.prop2, etc., have many want able hook obj.<anything>, , handle in general.

however, __getattr__ still won't let override happens attributes exist, lets hook in blanket handling use of attributes otherwise raise attributeerror. using __getattribute__ lets hook in handle everything, normal attributes have worked without messing __getattribute__. because of this, using __getattribute__ has potential break basic behavior, should use if considered using __getattr__ , wasn't enough. can have noticeable performance impact. might instance need use __getattribute__ if you're wrapping class defines attributes, , want able wrap attributes in custom way, work usual in situations custom behavior in other situations.

finally, writing own descriptor advanced task. property descriptor, , 95% of cases it's 1 you'll need. simple example of why might write own descriptor given here: basically, might if otherwise have write several propertys similar behavior; descriptor lets factor out common behavior avoid code repetition. custom descriptors used, instance, drive systems like django , sqlalchemy. if find writing @ level of complexity might need write custom descriptor.

in example, property best choice. (not always) red flag if you're doing if name == 'somespecificname' inside __getattribute__. if need specially handle 1 specific name, can without stooping level of __getattribute__. likewise, doesn't make sense write own descriptor if write __get__ have written in property's getter method.


Comments

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -