class AngryBird:
def __init__(self):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self.x = 0
self.y = 0
class
keyword to declare classes.constructor
== __init__
this
== self
class AngryBird:
def __init__(self):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self.x = 0
self.y = 0
def move_up_by(self, delta):
self.y += delta
Note how you do not need to define self
it is already bound to the class.
It is good practice to write a comment at the beginning of your class, describing the class.
Dunder Methods
i.e. __init__()
lets you make sure all relevant attributes are set to their proper values when an object is created from the class.
The self
keyword refers to the current object that you are working with.
Method is a function that is part of a class.
class AngryBird:
def __init__(self):
self.x = 0
self.y = 0
def move_up_by(self, delta):
self.y += delta
bird = AngryBird()
print(bird)
print(bird.y)
bird.move_up_by(5)
print(bird.y)
class AngryBird:
def __init__(self, x=0, y=0):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self._x = x
self._y = y
def move_up_by(self, delta):
self._y += delta
def get_x(self):
return self._x
def get_y(self):
return self._y
All instance variables should be considered non-public
**slots** : Dunder class variable used to reserve memory for the instance variables that you know will you will use.
class AngryBird:
__slots__ = ['_x', '_y']
def __init__(self, x=0, y=0):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self._x = x
self._y = y
def move_up_by(self, delta):
self._y += delta
def get_x(self):
return self._x
def get_y(self):
return self._y
__repr__()
to override the behavior of printing out a class in a verbose manner.class AngryBird:
__slots__ = ['_x', '_y']
def __init__(self, x=0, y=0):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self._x = x
self._y = y
def move_up_by(self, delta):
self._y += delta
def get_x(self):
return self._x
def get_y(self):
return self._y
def __repr__(self):
return f"<AngryBird ({self._x}, {self._y})>"
Getters
property
that you can apply to a method to make it readable. @property
def x(self):
return self._x
@property
def y(self):
return self._y
bird = AngryBird()
print(bird.x, bird.y)
Setters
class AngryBird:
def __init__(self, x=0, y=0):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self._x = x
self._y = y
def move_up_by(self, delta):
self._y += delta
@property
def x(self):
return self._x
@x.setter
def x(self, value):
if value < 0:
value = 0
self._x = value
@property
def y(self):
return self._y
@y.setter
def y(self, value):
if value < 0:
value = 0
self._y = value
List comprehensions are the equivalent of wrapped up filter namp array methods while also allowing nested loops.
new_list = [expression for member in iterable]
expression : member itself, a call to a methd, or any other valid expression that returns a value.
member : object or value in the list or iterable.
iterable : iterable.
new_list = [expression for member in iterable (if conditional)]
sentence = 'Mary, Mary, quite contrary, how does your garden grow?'
def is_consonant(letter):
vowels = "aeiou"
return letter.isalpha() and letter.lower() not in vowels
consonants = [i for i in sentence if is_consonant(i)]
print(consonants)
# Prints ['M', 'r', 'y', 'M', 'r', 'y', 'q', 't', 'c',
# 'n', 't', 'r', 'r', 'y', 'h', 'w', 'd', 's', 'y',
# 'r', 'g', 'r', 'd', 'n', 'g', 'r', 'w']
When to not use list comprehensions - List comprehensions may make your code run more slowly or use more memory. - You can use nest lists to create matrices.