Lab 5 Object Oriented

Réussis tes devoirs et examens dès maintenant avec Quizwiz!

An attribute is a variable stored within an object. The Backpack class has two attributes: name and contents

In the body of the class definition, attributes are assigned and accessed via the name self. This name refers to the object internally once it has been created.

To practice these principles, consider adding a static attribute to the Backpack class to serve as a counter for a unique ID

In the constructor for the Backpack class, add an instance variable called self.ID. Set this ID based on the static ID variable, then increment the static ID so that the next Backpack object will have a different ID.

Python allows a class' variables to be changed directly

For example, to close a knapsack I don't need a method, I can directly change the attribute

In Python, a class's constructor is always named __init__().

remember that packages used to require a __init__.py iirc

How to access attributes from a superclass in a subclass

self.attribute not superclass.attribute

If the __hash__() method is not defined, the default hash value is the object's memory address

(accessible via the built-in function id()) divided by 16, rounded down to the nearest integer. However, two objects that compare as equal via the __eq__() magic method must have the same hash value.

Takes no positional arguments but one was given error can occur if the self argument is given to the definition of method functions I was getting this error, and eventually figure out what causes it, changed my code did %run on the relevant file, and continued to get the same error on the object already created in ipython. I then repeated all the declarations and modifications to the jetpack object and things worked fine. This leads me to believe that in Ipython an object keeps the functions and methods of the time when the object was created, even if those attributes and methods are changed later

Another common cause of the error is overriding built-in functions and classes by declaring a function with the same name. We declared an str function that shadows the built-in str class. When we call str(), we are actually calling our own function and not the built-in class. Make sure you don't have functions that share the same name with built-ins.

A class is a blueprint for an object that binds together specified variables and routines.

Creating and using custom classes is often a good way to write clean, efficient, well-designed programs.

While we may even build in error checking into certain functions, if we are accidently using a different function or in some other way avoid the place we placed the error checking to begin with the error may end up never being checked

In particular, in the backpack example, I have a put method for the class to "place an item" in the backpack, it does this by appending to a list of items it contains, however, if I don't use the put method and instead use the actual append directly on the list of contents, the error checking of the put method will never done. This is probably why some people make a big deal about make private data members/attributes (c++ term/python term) private, so that they can only be accessed with methods and functions that have complete functionality, and not by the similar functions used to code those functions that may lack desired functionality and leave the possibility for errors

Method Arithmetic Operator __add__() + __sub__() - __mul__() * __pow__() ** __truediv__() / __floordiv__() //

Method Comparison Operator __lt__() < __le__() <= __gt__() > __ge__() >= __eq__() == __ne__() != For more methods and details, see https://docs.python.org/3/reference/datamodel.html#special-method-names.

The first argument of each method must be self, to give the method access to the attributes and other methods of the class. The self argument is only included in the declaration of the class methods, not when calling the methods on an instantiation of the class.

Python automatically passes self to the class method when it is called, so a method that takes no arguments gets passed one which causes the error. (https://bobbyhadz.com/blog/python-typeerror-takes-0-positional-arguments-but-1-was-given#:~:text=The%20Python%20%22TypeError%3A%20takes%200,doesn't%20take%20any%20arguments.) If your method doesn't make use of the self argument, you can declare a static method and in doing so not write the usual "self" in parentheses

In Python, the built-in set and dict structures use hash values to store and retrieve objects in memory quickly. If an object is unhashable, it cannot be put in a set or be used as a key in a dictionary.

See https://docs.python.org/3/glossary.html#term-hashable for details.

The caret operator ˆ is a bitwise XOR (exclusive or). The bitwise AND operator & and the bitwise OR operator | are also good choices to use.

See https://docs.python.org/3/reference/datamodel.html#object.__hash__ for more on hashing.

Method Operation Trigger Function __bool__() Truth value bool() __len__() Object length or size len() __repr__() Object representation repr() __getitem__() Indexing and slicing self[index] __setitem__() Assignment via indexing self[index] = x __iter__() Iteration over the object iter() __reversed__() Reverse iteration over the object reversed() __contains__() Membership testing in

See https://docs.python.org/3/reference/datamodel.html#special-method-names for more details and documentation on all magic methods

A class needs a method called a constructor that is called whenever the class instantiates a new object

The constructor specifies the initial state of the object.

The __eq__() magic method is used to determine if two objects are equal, and is invoked by the == operator

The __str__() magic method returns the string representation of an object. This method is invoked by str() and used by print().

Since Knapsack inherits from Backpack, a knapsack object is a backpack object. All methods defined in the Backpack class are available as instances of the Knapsack class. For example, the dump() method is available even though it is not defined explicitly in the Knapsack class.

The built-in function issubclass(is_subclass_of, superclass?) shows whether or not one class is derived from another. Similarly, isinstance() indicates whether or not an object belongs to a specified class hierarchy. Finally, hasattr() shows whether or not a class or object has a specified attribute or method.

A Python class is a code block that defines a custom object and determines its behavior.

The class key word defines and names a new class. There are other statements, and they are indented and begin on the next line

The first argument of each method must be self, to give the method access to the attributes and other methods of the class.

The self argument is only included in the declaration of the class methods, not when calling the methods on an instantiation of the class. In those cases use the name of the particular instance rather than self

Often we will write things like self.attributeName=attributeName as the second attributeName here is in reference to the value passed to the constructor

This feels really weird to me, but is correct

Individual class methods can also be static. A static method cannot be dependent on the attributes of individual instances of the class, so there can be no references to self inside the body of the method and self is not listed as an argument in the function definition

Thus static methods only have access to static attributes and other static methods. Include the tag @staticmethod above the function definition to designate a method as static Ie a method that is shared by all instances of the class, and this is different somehow from how methods already work I guess

it is often better to inherit the methods and attributes from an existing class rather than create a new class from scratch. This creates a class hierarchy: a class that inherits from another class is called a subclass, and the class that a subclass inherits from is called a superclass.

To define a subclass, add the name of the superclass as an argument at the end of the class declaration.

Attributes that are accessed through self are called instance attributes because they are bound to a particular instance of the class. In contrast, a static attribute is one that is shared between all instances of the class.

To make an attribute static, declare it inside of the class block but outside of any of the class's methods, and do not use self. Since the attribute is not tied to a specific instance of the class, it may be accessed or changed via the class name without even instantiating the class at all. class Backpack: # ... brand = "Adidas" # Backpack.brand is a static attribute. Backpack.brand = "Nike" changes the brand of all backpack objects from Adidas to Nike

Magic methods also facilitate object comparisons. For example, the __lt__() method corresponds to the < operator. Suppose one backpack is considered "less" than another if it has fewer items in its list of contents

Using the < binary operator on two Backpack objects calls __lt__(). As with addition, the object on the left side of the < operator is passed to __lt__() as self, and the object on the right is passed in as other.

iirc C++ constructors have the same name as the class, python constructors are written def __init__(arguments): with the constructor of a superclass being called with superclass__init__(arguments): the superclass constructor will then set the attributes it does when it gets to the given self.attribute line for each one, this would give an error if we forgot to list one of it's arguments and it got to that self.argument line If the superclass constructor has a keyword argument its default value should not be specified again when calling the superclass constructor within a subclass constructor(I've never actually tried it to see what would happen, but I assume it would override giving a different default value to the same argument in the overriding constructor of a subclass) Note the subclass must list all of it's arguments including any that are also in the constructor of the superclass. The constructor of the superclass can still be used however to set the arguments between the shared classes

a subclass constructor may call a superclass constructor, if it does, the subclass constructor need not define the values the superclass constructor defines, as the superclass constructor already defines them

The constructor specifies the initial state of the object.

class Backpack: """A Backpack object class. Has a name and a list of contents. Attributes: name (str): the name of the backpack's owner. contents (list): the contents of the backpack. """ def __init__(self, name): # This function is the constructor. """Set the name and initialize an empty list of contents. Parameters: name (str): the name of the backpack's owner. """ self.name = name # Initialize some attributes. self.contents = []

In addition to storing variables as attributes, classes can have functions attached to them. A function that belongs to a specific class is called a method.

class Backpack: # ... def put(self, item): """Add an item to the backpack's list of contents.""" self.contents.append(item) # Use 'self.contents', not just 'contents'. def take(self, item): """Remove an item from the backpack's list of contents.""" self.contents.remove(item)

The more common magic methods define how an object behaves with respect to addition and other binary operations. For example, how should addition be defined for backpacks? A simple option is to add the number of contents. Then if backpack A has 3 items and backpack B has 5 items, A + B should return 8. To incorporate this idea, we implement the __add__() magic method.

class Backpack: # ... def __add__(self, other): """Add the number of contents of each Backpack.""" return len(self.contents) + len(other.contents) I assume from this that python itself must contain code somewhere associating each magic method with some particular functionality, in this particular case that the __add__ magic method should correspond to a plus sign Using the + binary operator on two Backpack objects calls the class's __add__() method. The object on the left side of the + is passed in to __add__() as self and the object on the right side of the + is passed in as other

The following simple __hash__() method for the Backpack class conforms to this rule and returns an integer

class Backpack: # ... def __hash__(self): return hash(self.name) ^ hash(self.color) ^ hash(len(self.contents))

Forgetting the parentheses after a method may result in an error

complex() first argument must be a string or a number, not 'method' in this case the inerpreter got to the method without the parentheses and stopped as it was expecting a number and without the parentheses it treated it as a method object

If methods from the superclass need to be changed for the subclass, they can be overridden by defining them again in the subclass. New methods can be included normally.

def put(self, item): # Override the put() method. """If the knapsack is untied, use the Backpack.put() method.""" if self.closed: print("I'm closed!") else: # Use Backpack's original put(). Backpack.put(self, item) Note: This is how the superclass functions are accessed in overriding defintions in a subclass

I still don't think there's a way to make statments like isinstance(my_knapsack, class1 and class2)

instead of isinstance(mybackpack,class1) and isinstance(mybackpack,class2)

To create an actual backpack object, call the class name like a function. set a variable name equal to the class name passing the arguments the class constructor takes into the class name all the positional arguments must be given values, if the constructor takes name and color it must be given both a name and color This triggers the constructor and returns a new instance of the class, an object whose type is the class.

my_backpack = Backpack("Fred") remember that the constructor took a name print(my_backpack.name, my_backpack.contents) Fred [] my_backpack.name = "George" print(my_backpack.name, my_backpack.contents) George []

list.append can only take one argument

that is to say that it cannot append to items to a list at once

constructor will have define the attributes with self.attribute

the methods are defined like any other functions, in this particular case they happen to be indented because they are within the scope of the class class name:

constructors should have as arguments self it may also have data to be given to attributes it will specify

the top line of the class definition has no parentheses if it is not a subclass of anything other than class object. The name of a superclass can go in parentheses just after the class name (can a class inherit from two superclasses?


Ensembles d'études connexes

RN At-Risk and Vulnerable Populations and Related Effects on Health

View Set

MGMT 365: Chapter 11 - Total Rewards and Compensation

View Set

RAD 111 Exam question bank (exams 1 - 8)

View Set

Packard AP Chemistry Final Exam Semester 2

View Set

Introduction to Health Informatics

View Set

Art history Section 2 study guide

View Set