面对对象编程估计我们最早接触到的就是__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('','clube'), NumberCard('','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

python面对对象编程----2:__init__的更多相关文章

  1. python面对对象编程------4:类基本的特殊方法__str__,__repr__,__hash__,__new__,__bool__,6大比较方法

    一:string相关:__str__(),__repr__(),__format__() str方法更面向人类阅读,print()使用的就是str repr方法更面对python,目标是希望生成一个放 ...

  2. python面对对象编程----------7:callable(类调用)与context(上下文)

    一:callables callables使类实例能够像函数一样被调用 如果类需要一个函数型接口这时用callable,最好继承自abc.Callable,这样有些检查机制并且一看就知道此类的目的是c ...

  3. python面对对象编程---------6:抽象基类

    抽象基本类的几大特点: 1:要定义但是并不完整的实现所有方法 2:基本的意思是作为父类 3:父类需要明确表示出那些方法的特征,这样在写子类时更加简单明白 用抽象基本类的地方: 1:用作父类 2:用作检 ...

  4. python面对对象编程-------5:获取属性的四种办法:@property, __setattr__(__getattr__) ,descriptor

    一:最基本的属性操作 class Generic: pass g= Generic() >>> g.attribute= "value" #创建属性并赋值 > ...

  5. python面对对象编程中会用到的装饰器

    1.property 用途:用来将对像的某个方法伪装成属性来提高代码的统一性. class Goods: #商品类 discount = 0.8 #商品折扣 def __init__(self,nam ...

  6. python面对对象编程----1:BlackJack(21点)

    昨天读完了<Mastering Object-oriented Python>的第一部分,做一些总结. 首先,第一部分总过八章,名字叫Pythonic Classes via Specia ...

  7. python面对对象编程------3:写集合类的三种方法

    写一个集合类的三种方法:wrap,extend,invent 一:包装一个集合类 class Deck: def __init__( self ): self._cards = [card6(r+1, ...

  8. Python学习6——再谈抽象(面对对象编程)

    1.对象魔法 在面对对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法. 使用对象而非全局变量以及函数的原因有多个,而最重要的好处不过以下几点: 多态:可对不同类型的对象 ...

  9. python 面对对象基础

    目录 面向对象基础 面向对象编程(抽象) 类与对象 给对象定制独有的特征 对象的属性查找顺序 类与对象的绑定方法 类与数据类型 对象的高度整合 面向对象基础 面向对象编程(抽象) 回顾一下 面向过程编 ...

随机推荐

  1. Python学习笔记:02数据类型

    Python 数据类型 python中标准的数据类型有 基础类型 整型(长整型) 浮点型 复数型 布尔型 序列类型 字符串 列表 元组 字典 整型 整型和长整型并不严格区分,整型int的表达范围和计算 ...

  2. laravel框架——保存用户登陆信息(session)

    public function inlog(Request $request) { //获取表单提交的数据 $input = $request->all(); //根本获取的数据去数据库中查询 ...

  3. SAR-303 xml validator验证框架

    // 配置文件详解 <mvc:annotation-driven validator="validator" /> <bean id="validato ...

  4. web client

    http://blog.csdn.net/borishuai/article/details/8676573 http://down.lusongsong.com/soft/696.html http ...

  5. handler.post(r)同一个线程的疑惑

    handler.post(r);是把r加到消息队列,但并未开辟新线程.等到消息被取出时才执行. package com.lei.handlethread; import android.os.Bund ...

  6. Linux命令之yes

    yes命令用于重复输出字符串(output a string repeatedly until killed).这个命令可以帮你自动回答命令行提示,例如,进入一个含有多个文件的目录,执行 " ...

  7. 14.4.2 Change Buffer 延迟写

    14.4.2 Change Buffer change buffer 是一个特殊的数据结构 用于cahce 改变的secondary index pages 当被影响的pages 不在buffer p ...

  8. hdu5126stars

    http://acm.hdu.edu.cn/showproblem.php?pid=5126 首先,对于一个询问,用容斥原理可以拆成8个询问,于是询问变成:给定一个四元组$(i,x_i,y_i,z_i ...

  9. [Design Pattern] Service Locator Pattern 简单案例

    Service Locator Pattern,即服务定位模式,用于定位不同的服务.考虑到 InitialContext::lookup 的成本比较高,提供了 Cache 类缓存以定位到的服务. 代码 ...

  10. POJ2533 Longest ordered subsequence

    Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 41984   Acc ...