zoukankan      html  css  js  c++  java
  • python面对对象编程----2:__init__

    面对对象编程估计我们最早接触到的就是__init__了,也就是实例的初始化处理过程:

    1:来看看最基础的__init__

     1 class Card(object):               #抽象类Card,并不用于实例化
     2     def __init__( self, rank, suit ):
     3         self.suit= suit
     4         self.rank= rank
     5         self.hard, self.soft = self._points()     
     6         print("try")
     7 
     8 class NumberCard( Card ):
     9     def _points( self ):
    10         return int(self.rank), int(self.rank)
    11 
    12 class AceCard( Card ):
    13     def _points( self ):
    14         return 1, 11
    15 
    16 class FaceCard( Card ):
    17 
    18     def _points( self ):
    19         return 10, 10
    20 
    21 
    22 cards = [ AceCard('A', 'spade'), NumberCard('2','clube'), NumberCard('3','diamond'),]    
    #注意此地,若子类没有写__init__方法,那么在实例化时会完整的继承实现一遍父类的__init__,所以这里会打印出三个'try'

    2:在子类中使用__init__

     在子类中写__init__方法的目的要么是实际传入参数(此地),要么是添加其他属性或者操作,都可以通过super()来获得父类__init__方法。否则不用写就会自动继承执行父类的__init__方法
     1 class Card:
     2     def __init__( self, rank, suit, hard, soft ):
     3         self.rank= rank
     4         self.suit= suit
     5         self.hard= hard
     6         self.soft= soft
     7 
     8 class NumberCard( Card ):
     9     def __init__( self, rank, suit ):
    10         super().__init__( str(rank), suit, rank, rank )     #在子类中使用super().__init__(*args)要传入除了self外所有参数
    11 
    12 class AceCard( Card ):
    13     def __init__( self, rank, suit ):
    14         super().__init__( "A", suit, 1, 11 )         
    15 
    16 class FaceCard( Card ):
    17     def __init__( self, rank, suit ):
    18         super().__init__( {11: 'J', 12: 'Q', 13: 'K' }[rank], suit,10, 10 )

    3:没有__init__方法:

      完全没有__init__方法的类经常是作为策略类使用,策略类就是把一些列相关操作集合起来的类,通过方法传入的参数来进行一些列操作

      例如下面的游戏操作策略类,通过传入手牌这一参数决定了每一方法的使用。

    1 class GameStrategy:
    2     def insurance( self, hand ):        #hand是手牌
    3         return False
    4     def split( self, hand ):
    5         return False
    6     def double( self, hand ):
    7         return False
    8     def hit( self, hand ):
    9         return sum(c.hard for c in hand.cards) <= 17

    4:若init方法太繁琐,有时用 静态方法 生成并且返回实例会更清晰简洁

      这里模拟了庄家发牌的过程,庄家手上先拿到n张牌(n个人),然后通过静态方法split(分发)出去

     1 class Hand5:
     2     def __init__( self, dealer_card, *cards ):
     3         self.dealer_card= dealer_card
     4         self.cards = list(cards)
     5 
     6     @staticmethod
     7     def freeze( other ):      #冻结手牌
     8         hand= Hand5( other.dealer_card, *other.cards )
     9         return hand
    10 
    11     @staticmethod
    12     def split( other, card0, card1 ):
    13         hand0= Hand5( other.dealer_card, other.cards[0], card0 )
    14         hand1= Hand5( other.dealer_card, other.cards[1], card1 )
    15         return hand0, hand1
    16 
    17     def __str__( self ):
    18         return ", ".join( map(str, self.cards) )
    19 
    20 d = Deck()
    21 h = Hand5( d.pop(), d.pop(), d.pop() )
    22 s1, s2 = Hand5.split( h, d.pop(), d.pop() )
    5:另一种初始化属性的方法:

      #常用情况:
    1
    class Player: 2 def __init__( self, table, bet_strategy, game_strategy ): 3 self.bet_strategy = bet_strategy 4 self.game_strategy = game_strategy 5 self.table= table 6 7 #也可以写成这样 8 class Player2: 9 def __init__( self, **kw ): 10 """Must provide table, bet_strategy, game_strategy.""" 11 self.__dict__.update( kw )    #__dict__见下,dict.update(name='pd',...)可添加键值对
      
    P = Player2(table = table,bet_strategy = bet_strategy, game_strategy = game_strategy) #注意实例化的参数形式   
    12 13 14 #上面方法虽然扩展性好,但是implicit。适合用于做基类,在此基础上可以明确声明一部分初始化参数 15 class Player3( Player ): 16 def __init__( self, table, bet_strategy, game_strategy, **extras): 17 self.bet_strategy = bet_strategy 18 self.game_strategy = game_strategy 19 self.table= table 20 self.__dict__.update( extras )
     1 >>> class aha(object):
     2 ...     def __init__(self,name,age):
     3 ...             self.name = name
     4 ...             self.age = age
     5 ...
     6 >>> aha.__dict__
     7 dict_proxy({'__dict__': <attribute '__dict__' of 'aha' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'aha' objects>, '__doc__': None, '__init__': <function __init__ at 0x0000000002C35908>})
     8 >>> a=aha('pd',12)
     9 >>> a.__dict__
    10 {'age': 12, 'name': 'pd'}
    关于__dict__

    6:带检验初始化

     1 class ValidPlayer:
     2     def __init__( self, table, bet_strategy, game_strategy ):
     3         assert isinstance( table, Table )                   #assert遇错误会报错并且中断程序
     4         assert isinstance( bet_strategy, BettingStrategy )
     5         assert isinstance( game_strategy, GameStrategy )
     6         self.bet_strategy = bet_strategy
     7         self.game_strategy = game_strategy
     8         self.table= table
     9 
    10 #但这违背了python动态语言的特性,在用python时我们希望能够动态传入,但是应该写doc给programmer提醒,并且若有人没有按动态传入,可log后再分析
    11 
    12 class ValidPlayer:
    13     """
    14         Creates a new player associated with a table,and configured with proper betting and play strategies
    15         :param table: an instance of :class:`Table`
    16         :param bet_strategy: an instance of :class:`BettingStrategy`
    17         :param game_strategy: an instance of :class:`GameStrategy`
    18         通过 ValidPlayer.__doc__ 访问这段话
    19     """
    20     def __init__( self, table, bet_strategy, game_strategy ):
    21         assert isinstance( table, Table )                   #assert遇错误会报错中断
    22         assert isinstance( bet_strategy, BettingStrategy )
    23         assert isinstance( game_strategy, GameStrategy )
    24         self.bet_strategy = bet_strategy
    25         self.game_strategy = game_strategy
    26         self.table= table
  • 相关阅读:
    九度 1363 欢乐斗地主
    九度 1377 缓变序列
    九度 1376 最近零子序列
    转几篇关于linux下AT&T汇编的帖子
    九度 1358 陈博的平均主义
    九度 1394 五连击数组
    HDU 2817 A sequence of numbers
    HDU 1867 A + B for you again
    HDU 1753 大明A+B
    HDU 1715 大菲波数
  • 原文地址:https://www.cnblogs.com/pengsixiong/p/5381381.html
Copyright © 2011-2022 走看看