您的位置:首页 > 编程语言 > Python开发

python面对对象编程----2:__init__

2016-04-12 09:21 731 查看
面对对象编程估计我们最早接触到的就是__init__了,也就是实例的初始化处理过程:

1:来看看最基础的__init__

class Card(object):               #抽象类Card,并不用于实例化
def __init__( self, rank, suit ):
self.suit= suit
self.rank= rank
self.hard, self.soft = self._points()
print("try")

class NumberCard( Card ):
def _points( self ):
return int(self.rank), int(self.rank)

class AceCard( Card ):
def _points( self ):
return 1, 11

class FaceCard( Card ):

def _points( self ):
return 10, 10

cards = [ AceCard('A', 'spade'), NumberCard('2','clube'), NumberCard('3','diamond'),]    
#注意此地,若子类没有写__init__方法,那么在实例化时会完整的继承实现一遍父类的__init__,所以这里会打印出三个'try'


2:在子类中使用__init__

在子类中写__init__方法的目的要么是实际传入参数(此地),要么是添加其他属性或者操作,都可以通过super()来获得父类__init__方法。否则不用写就会自动继承执行父类的__init__方法


class Card:
def __init__( self, rank, suit, hard, soft ):
self.rank= rank
self.suit= suit
self.hard= hard
self.soft= soft

class NumberCard( Card ):
def __init__( self, rank, suit ):
super().__init__( str(rank), suit, rank, rank )     #在子类中使用super().__init__(*args)要传入除了self外所有参数

class AceCard( Card ):
def __init__( self, rank, suit ):
super().__init__( "A", suit, 1, 11 )

class FaceCard( Card ):
def __init__( self, rank, suit ):
super().__init__( {11: 'J', 12: 'Q', 13: 'K' }[rank], suit,10, 10 )


3:没有__init__方法:

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

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

class GameStrategy:
def insurance( self, hand ):        #hand是手牌
return False
def split( self, hand ):
return False
def double( self, hand ):
return False
def hit( self, hand ):
return sum(c.hard for c in hand.cards) <= 17


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

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

class Hand5:
def __init__( self, dealer_card, *cards ):
self.dealer_card= dealer_card
self.cards = list(cards)

@staticmethod
def freeze( other ):      #冻结手牌
hand= Hand5( other.dealer_card, *other.cards )
return hand

@staticmethod
def split( other, card0, card1 ):
hand0= Hand5( other.dealer_card, other.cards[0], card0 )
hand1= Hand5( other.dealer_card, other.cards[1], card1 )
return hand0, hand1

def __str__( self ):
return ", ".join( map(str, self.cards) )

d = Deck()
h = Hand5( d.pop(), d.pop(), d.pop() )
s1, s2 = Hand5.split( h, d.pop(), d.pop() )


5:另一种初始化属性的方法:


  #常用情况:
1 class Player:
def __init__( self, table, bet_strategy, game_strategy ):
self.bet_strategy = bet_strategy
self.game_strategy = game_strategy
self.table= table

#也可以写成这样
class Player2:
def __init__( self, **kw ):
"""Must provide table, bet_strategy, game_strategy."""
self.__dict__.update( kw )    #__dict__见下,dict.update(name='pd',...)可添加键值对
  
P = Player2(table = table,bet_strategy = bet_strategy, game_strategy = game_strategy) #注意实例化的参数形式   

#上面方法虽然扩展性好,但是implicit。适合用于做基类,在此基础上可以明确声明一部分初始化参数
class Player3( Player ):
def __init__( self, table, bet_strategy, game_strategy, **extras):
self.bet_strategy = bet_strategy
self.game_strategy = game_strategy
self.table= table
self.__dict__.update( extras )


>>> class aha(object):
...     def __init__(self,name,age):
...             self.name = name
...             self.age = age
...
>>> aha.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'aha' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'aha' objects>, '__doc__': None, '__init__': <function __init__ at 0x0000000002C35908>})
>>> a=aha('pd',12)
>>> a.__dict__
{'age': 12, 'name': 'pd'}


关于__dict__

6:带检验初始化

class ValidPlayer:
def __init__( self, table, bet_strategy, game_strategy ):
assert isinstance( table, Table )                   #assert遇错误会报错并且中断程序
assert isinstance( bet_strategy, BettingStrategy )
assert isinstance( game_strategy, GameStrategy )
self.bet_strategy = bet_strategy
self.game_strategy = game_strategy
self.table= table

#但这违背了python动态语言的特性,在用python时我们希望能够动态传入,但是应该写doc给programmer提醒,并且若有人没有按动态传入,可log后再分析

class ValidPlayer:
"""
Creates a new player associated with a table,and configured with proper betting and play strategies
:param table: an instance of :class:`Table`
:param bet_strategy: an instance of :class:`BettingStrategy`
:param game_strategy: an instance of :class:`GameStrategy`
通过 ValidPlayer.__doc__ 访问这段话
"""
def __init__( self, table, bet_strategy, game_strategy ):
assert isinstance( table, Table )                   #assert遇错误会报错中断
assert isinstance( bet_strategy, BettingStrategy )
assert isinstance( game_strategy, GameStrategy )
self.bet_strategy = bet_strategy
self.game_strategy = game_strategy
self.table= table
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: