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
原文地址:https://www.cnblogs.com/pengsixiong/p/5381381.html