More Related Content Similar to Python Descriptors Demystified Similar to Python Descriptors Demystified (20) Python Descriptors Demystified1. Descriptors
Python's most obscure language feature demystified.
In 5 minutes.
Chris Beaumont
@BeaumontChris
graduate student, astrophysics
Harvard University / University of Hawaii
4. class Email(object):
def __init__(self, sender, subject, message):
self.sender_widget = QLineEdit(sender)
self.subject_widget = QLineEdit(subject)
self.message_widget = QLineEdit(message)
How does other code
interact with
email data?
9. e = Email()
sub = e.subject
e.subject = 'hi there'
class Email(object):
...
@property
def subject(self):
return self.subject_widget.text()
@subject.setter
def subject(self, subject):
self.subject_widget.setText(subject)
...
10. e = Email()
sub = e.subject
e.subject = 'hi there'
class Email(object):
...
@property
def subject(self):
return self.subject_widget.text()
@subject.setter
def subject(self, subject):
self.subject_widget.setText(subject)
...
Nice.
11. class Email(object):
def __init__(self, sender, subject, message):
self._sender_widget = QLineEdit(sender)
self._subject_widget = QLineEdit(subject)
self._message_widget = QLineEdit(message)
@property
def sender(self):
return self._sender_widget.text()
@sender.setter
def sender(self, sender):
self._sender_widget.setText(sender)
@property
def subject(self):
return self._subject_widget.text()
@subject.setter
def subject(self, subject):
self._subject_widget.setText(subject)
@property
def message(self):
return self._message_widget.text()
@message.setter
def message(self, message):
self._message_widget.setText(message)
12. class Email(object):
def __init__(self, sender, subject, message):
self._sender_widget = QLineEdit(sender)
self._subject_widget = QLineEdit(subject)
self._message_widget = QLineEdit(message)
@property
def sender(self):
return self._sender_widget.text()
@sender.setter
def sender(self, sender):
self._sender_widget.setText(sender)
@property
def subject(self):
return self._subject_widget.text()
@subject.setter
def subject(self, subject):
self._subject_widget.setText(subject)
@property
def message(self):
return self._message_widget.text()
@message.setter
def message(self, message):
self._message_widget.setText(message)
Gross
14. class TextWrapper(object):
def __init__(self, widget_name):
self.widget_name = widget_name
def __get__(self, object):
widget = getattr(object, self.widget_name)
return widget.text()
def __set__(self, object, value):
widget = getattr(object, self.widget_name)
widget.setText(value)
class Email(object):
sender = TextWrapper('sender_widget')
subject = TextWrapper('subject_widget')
message = TextWrapper('message_widget')
def __init__(self, sender, subject, message):
self.sender_widget = QLineEdit(sender)
self.subject_widget = QLineEdit(subject)
self.message_widget = QLineEdit(message)
...
...
15. class TextWrapper(object):
def __init__(self, widget_name):
self.widget_name = widget_name
def __get__(self, object):
widget = getattr(object, self.widget_name)
return widget.text()
def __set__(self, object, value):
widget = getattr(object, self.widget_name)
widget.setText(value)
class Email(object):
sender = TextWrapper('sender_widget')
subject = TextWrapper('subject_widget')
message = TextWrapper('message_widget')
def __init__(self, sender, subject, message):
self.sender_widget = QLineEdit(sender)
self.subject_widget = QLineEdit(subject)
self.message_widget = QLineEdit(message)
e = Email()
sender = e.sender
e.sender = 'foo'
...
...
16. e = Email()
sender = e.sender
e.sender = 'foo'
...
class TextWrapper(object):
def __init__(self, widget_name):
self.widget_name = widget_name
def __get__(self, object):
widget = getattr(object, self.widget_name)
return widget.text()
def __set__(self, object, value):
widget = getattr(object, self.widget_name)
widget.setText(value)
class Email(object):
sender = TextWrapper('sender_widget')
subject = TextWrapper('subject_widget')
message = TextWrapper('message_widget')
def __init__(self, sender, subject, message):
self.sender_widget = QLineEdit(sender)
self.subject_widget = QLineEdit(subject)
self.message_widget = QLineEdit(message)
17. e = Email()
sender = e.sender
e.sender = 'foo'
class TextWrapper(object):
def __init__(self, widget_name):
self.widget_name = widget_name
def __get__(self, object):
widget = getattr(object, self.widget_name)
return widget.text()
def __set__(self, object, value):
widget = getattr(object, self.widget_name)
widget.setText(value)
class Email(object):
sender = TextWrapper('sender_widget')
subject = TextWrapper('subject_widget')
message = TextWrapper('message_widget')
def __init__(self, sender, subject, message):
self.sender_widget = QLineEdit(sender)
self.subject_widget = QLineEdit(subject)
self.message_widget = QLineEdit(message)
18. e = Email()
sender = e.sender
e.sender = 'foo'
Nice.
class TextWrapper(object):
def __init__(self, widget_name):
self.widget_name = widget_name
def __get__(self, object):
widget = getattr(object, self.widget_name)
return widget.text()
def __set__(self, object, value):
widget = getattr(object, self.widget_name)
widget.setText(value)
class Email(object):
sender = TextWrapper('sender_widget')
subject = TextWrapper('subject_widget')
message = TextWrapper('message_widget')
def __init__(self, sender, subject, message):
self.sender_widget = QLineEdit(sender)
self.subject_widget = QLineEdit(subject)
self.message_widget = QLineEdit(message)
19. e = Email()
sender = e.sender
e.sender = 'foo'
Nice.
Nice.
class TextWrapper(object):
def __init__(self, widget_name):
self.widget_name = widget_name
def __get__(self, object):
widget = getattr(object, self.widget_name)
return widget.text()
def __set__(self, object, value):
widget = getattr(object, self.widget_name)
widget.setText(value)
class Email(object):
sender = TextWrapper('sender_widget')
subject = TextWrapper('subject_widget')
message = TextWrapper('message_widget')
def __init__(self, sender, subject, message):
self.sender_widget = QLineEdit(sender)
self.subject_widget = QLineEdit(subject)
self.message_widget = QLineEdit(message)
20. e = Email()
sender = e.sender
e.sender = 'foo'
Nice.
Nice.
Meh?class TextWrapper(object):
def __init__(self, widget_name):
self.widget_name = widget_name
def __get__(self, object):
widget = getattr(object, self.widget_name)
return widget.text()
def __set__(self, object, value):
widget = getattr(object, self.widget_name)
widget.setText(value)
class Email(object):
sender = TextWrapper('sender_widget')
subject = TextWrapper('subject_widget')
message = TextWrapper('message_widget')
def __init__(self, sender, subject, message):
self.sender_widget = QLineEdit(sender)
self.subject_widget = QLineEdit(subject)
self.message_widget = QLineEdit(message)
24. Instance-specific data
class Foo(object):
x = Descriptor()
f1 = Foo()
f2 = Foo()
f1.x = 5
f2.x = 4
class Descriptor(object):
def __init__(self):
self._data = {}
def __get__(self, instance):
return self._data[instance]