\documentclass[14pt,compress,aspectratio=169]{beamer} \input{macros.tex} \title[OOP: Class Attributes]{Advanced Python} \subtitle{Object Oriented Programming: class attributes} \author[FOSSEE] {The FOSSEE Group} \institute[IIT Bombay] {Department of Aerospace Engineering\\IIT Bombay} \date[] {Mumbai, India} \begin{document} \begin{frame} \titlepage \end{frame} \begin{frame} \frametitle{Recap} \begin{itemize} \item Classes for encapsulation \item Inheritance \item \py{super,isinstance,issubclass} \item Containership \vspace*{0.3in} \item Look at class attributes/methods \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Class/instance attributes} \begin{itemize} \item So far: instance attributes \end{itemize} \begin{lstlisting} class A: x = 1 In []: a = A() In []: a.x Out[]: 1 In []: b = A() In []: assert b.x == a.x \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Class/instance attributes} \begin{lstlisting} class A: x = 1 In []: a, b = A(), A() In []: A.x = 2 In []: b.x Out[]: 2 \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Class/instance attributes: beware} \begin{lstlisting} class A: x = 1 In []: a = A() In []: a.x = 1 In []: A.x = 2 In []: a.x Out[]: ?? \end{lstlisting} \end{frame} \begin{frame} \frametitle{Understanding the scope} \begin{itemize} \item If \py{a.x} is not an instance attribute \item Python looks in the class for the attribute! \pause \vspace*{0.25in} \item So \py{a.x = 1} sets an instance attribute! \end{itemize} \end{frame} \begin{frame}[fragile,fragile] \frametitle{Class attribute scope} \begin{lstlisting} class A: x = 1 def f(self): return self.x + 1 In []: a = A() In []: a.f() \end{lstlisting} \pause \begin{lstlisting} Out[]: 2 \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Class methods} \begin{itemize} \item Can we have methods on the class? \end{itemize} \begin{lstlisting} class A: @classmethod def method(cls, x): print(cls, x) In []: A.method(1) 1 \end{lstlisting} \end{frame} \begin{frame} \frametitle{Class methods} \begin{itemize} \item \py{@classmethod} is a special decorator \item Makes the method a class method \item Implicit argument is the class (and not the instance) \item Useful when you don't want to construct the object \end{itemize} \end{frame} \begin{frame} \frametitle{Summary} \begin{itemize} \item Class attributes \item Class methods and the \py{@classmethod} decorator \end{itemize} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{frame}[plain, fragile] \frametitle{Exercise: Point class attribute} \begin{block}{} Create a simple \py{Point} class with class attributes \py{x, y} that default to 0.0. \end{block} \begin{lstlisting} In []: p = Point() In []: p.x, p.y Out[]: (0.0, 0.0) \end{lstlisting} \end{frame} \begin{frame}[plain, fragile] \frametitle{Solution} \begin{lstlisting} class Point: x = 0.0 y = 0.0 \end{lstlisting} \end{frame} \begin{frame}[plain, fragile] \frametitle{Exercise: classmethod} \begin{block}{} Create a simple \py{Point} class with instance attributes \py{x, y} but add a class method \py{polar(r, theta)} that takes coordinates in $(r, \theta)$ form but returns a suitable point. Remember that, $x=r \cos(\theta), y=r\sin(\theta)$. For example: \end{block} \begin{lstlisting} In []: p = Point.polar(1.0, 0.0) In []: p.x, p.y Out[]: (1.0, 0.0) \end{lstlisting} \end{frame} \begin{frame}[plain, fragile] \frametitle{Solution} \begin{lstlisting} from math import sin, cos class Point: def __init__(self, x=0.0, y=0.0): self.x = x self.y = y @classmethod def polar(cls, r, theta): x = r*cos(theta) y = r*sin(theta) return cls(x, y) \end{lstlisting} \end{frame} \end{document}