Python Programming: Class and Object Oriented Programming

Embed Size (px)

Text of Python Programming: Class and Object Oriented Programming

  • Python Intermediate Programming

    (chanshik@gmail.com)

    1

  • Python Intermediate Programming

    2

  • class

    3

  • class

    (class) (instance)

    (), ( ), ()

    class

    class

    self

    4

  • class

    class Account(object): num_accounts = 0 def __init__(self, name, balance): self.name = name self.balance = balance Account.num_accounts += 1 def __del__(self): Account.num_accounts -= 1 def deposit(self, amt): self.balance = self.balance + amt def withdraw(self, amt): self.balance = self.balance - amt def inquiry(self): return self.balance

    num_accounts

    5

  • __init__()

    >>> a = Account("Guido", 1000.00)>>> a.balance1000.0>>> a.deposit(100.00)>>> a.balance1100.0>>> Account.deposit(a, 100.00)>>> a.balance1200.0

    6

  • __init__() self (.)

    def __init__(self, name, balance): self.name = name # name

    name

    >>> b = Account("Bill", 2000.00)>>> b.name'Bill'

    (.)

    7

  • >>> class Foo(object):... def bar(self):... print("bar!")... def spam(self):... self.bar()... Foo.bar(self)... bar(self)...>>> Foo().spam()bar!bar!Traceback (most recent call last): File "", line 1, in File "", line 7, in spamNameError: name 'bar' is not defined 8

  • C++

    C++ this self

    self

    self.a = 10 # a = 20 #

    9

  • (inheritance)

    : (base class) (superclass) : (derived class) (subclass)

    class object

    object

    10

  • >>> class SavingAccount(Account):... def withdraw(self, amt):... if self.balance - amt >= 0:... self.balance -= amt... else:... raise ValueError("balance - amt < 0")...>>> s = SavingAccount("John", 10.00)>>> s.deposit(10.0) # Account.deposit(s, 10.0)>>> s.withdraw(30.0) # SavingAccount.withdraw(s, 30.0)Traceback (most recent call last): File "", line 1, in File "", line 6, in withdrawValueError: balance must be greater than zero

    11

  • (.)

    s.withdraw() SavingAccount

    s.deposit() Account deposit()

    __init__()

    __init__() __init__() __init__()

    12

  • class SavingAccount(Account): def __init__(self, name, balance, interest_rate): Account.__init__(self, name, balance) self.interest_rate = interest_rate

    Account.__init__()

    __init__() __init__()

    >

    13

  • self

    deposit() Account self

    class BasicSavingAccount(SavingAccount): def deposit(self, amt): self.withdraw(1.00) # SavingAccount.deposit(self, amt) #

    14

  • super()

    Python 3

    class BasicSavingAccount(SavingAccount): def deposit(self, amt): self.withdraw(1.00) super().deposit(amt)

    Python 2

    class BasicSavingAccount(SavingAccount): def deposit(self, amt): self.withdraw(1.00) super(BasicSavingAccount, self).deposit(amt)

    super(cls, instance)

    15

  • (multiple inheritance)

    class DepositCharge(object): fee = 1.00 def deposit_fee(self): self.withdraw(self.fee) # self.fee 1.00 ?

    class WithdrawCharge(object): fee = 2.00 def withdraw_fee(self): self.withdraw(self.fee) # self.fee 2.00 ?

    class FreeSavingAccount(BasicSavingAccount, DepositCharge, WithdrawCharge): def deposit(self, amt): self.deposit_fee() super().deposit(amt) def withdraw(self, amt): super().withdraw(amt)

    16

  • >>> f = FreeSavingAccount("John", 100.0, 0.10)>>> f.deposit_fee()>>> f.balance99.0 # self.fee 1.00>>> f.withdraw_fee()>>> f.balance98.0 # self.fee 1.00

    withdraw_fee() self.fee WithdrawCharge() DepositCharge()

    17

  • __mro__ (Method Resolution Order)

    >>> FreeSavingAccount.__mro__(, , , , , , )

    18

  • >>> class X(object):... pass...>>> class Y(X):... pass...>>> class Z(X, Y):... pass...Traceback (most recent call last): File "", line 1, in TypeError: Cannot create a consistent method resolutionorder (MRO) for bases X, Y

    19

  • Z TypeError

    X Y Y X X Y

    (mixin class)

    DepositCharge, WithdrawCharge

    20

  • (dynamic binding)

    obj.attr

    attr

    21

  • obj.name name

    (duck typing)" , , "

    22

    http://obj.name/

  • (static method)

    @staticmethod self

    >>> class Foo(object):... @staticmethod... def add(x, y):... return x + y...>>> Foo.add(1, 2)3>>> Foo.add(3, 4)7>>>

    23

  • >>> import time>>> class Date(object):... def __init__(self, year, month, day):... self.year = year... self.month = month... self.day = day... @staticmethod... def now():... t = time.localtime()... return Date(t.tm_year, t.tm_mon, t.tm_mday)... @staticmethod... def tomorrow():... t = time.localtime(time.time() + 86400)... return Date(t.tm_year, t.tm_mon, t.tm_mday)...>>> d = Date(2017, 1, 1)>>> d.year, d.month, d.day(2017, 1, 1)>>> now = Date.now()>>> now.year, now.month, now.day(2017, 1, 17)

    24

  • (class method)

    @classmethod cls

    >>> class Times(object):... factor = 1... @classmethod... def mul(cls, x):... return cls.factor * x...>>>>>> class TwoTimes(Times):... factor = 2...>>> TwoTimes.mul(2) # Times.mul(TwoTimes, 2) 4>>> TwoTimes.mul(4) # Times.mul(TwoTimes, 4) 8

    25

  • Date EuroDate

    >>> class EuroDate(Date):... def __str__(self):... return "%02d/%02d/%04d" % (self.day, ... self.month, ... self.year)...

    >>> e = EuroDate(2017, 1, 1)>>> type(e)

    >>> print(e)01/01/2017>>> now = EuroDate.now()>>> type(now)

    >>> print(now)

    26

  • EuroDate.now(), EuroDate.tomorrow() EuroDate Date

    >>> class Date(object):... def __init__(self, year, month, day):... self.year = year... self.month = month... self.day = day... @classmethod... def now(cls):... t = time.localtime()... return cls(t.tm_year, t.tm_mon, t.tm_mday)... @classmethod... def tomorrow(cls):... t = time.localtime(time.time() + 86400)... return cls(t.tm_year, t.tm_mon, t.tm_mday)...

    27

  • >>> class Date(object):... def __init__(self, year, month, day):... self.year = year... self.month = month... self.day = day... def __str__(self):... return "%04d-%02d-%02d" % (self.year, self.month, self.day)... @classmethod... def now(cls):... t = time.localtime()... return cls(t.tm_year, t.tm_mon, t.tm_mday)... @classmethod... def tomorrow(cls):... t = time.localtime(time.time() + 86400)... return cls(t.tm_year, t.tm_mon, t.tm_mday)...>>> print(Date.now())2017-01-17>>> print(EuroDate.now())17/01/2017

    28

  • ,

    >>> d = Date(2017, 1, 1)>>> now = d.now()>>> print(now)2017-01-18

    29

  • (property)

    >>> import math>>> class Circle(object):... def __init__(self, radius):... self.radius = radius... @property... def area(self):... return math.pi * self.radius ** 2... @property... def perimeter(self):... return 2 * math.pi * self.radius...>>> c = Circle(2.0)>>> c.radius2.0

    30

  • @property "()"

    >>> c.area12.566370614359172>>> c.perimeter12.566370614359172>>> c.area = 10Traceback (most recent call last): File "", line 1, in AttributeError: can't set attribute

    AttributeError

    31

  • (uniform access principle)

    c.radius c.area()

    "()"

    32

  • >>> class Foo(object):... def __init__(self, name):... self.__name = name... @property... def name(self):... return self.__name... @name.setter... def name(self, value):... if not isinstance(value, str):... raise TypeError("Must be a string")... self.__name = value... @name.deleter... def name(self):... raise TypeError("Can't delete name")...

    33

  • >>> f = Foo("John")>>> f.name = "Jane">>> f.name = 42Traceback (most recent call last): File "", line 1, in File "", line 10, in nameTypeError: Must be a string>>> del f.nameTraceback (most recent call last): File "", line 1, in File "", line 14, in nameTypeError: Can't delete name

    name @prope