面对对象编程估计我们最早接触到的就是__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. mysql报Fatal error encountered during command execution的解决办法

    连接字符串里加上 Allow User Variables=True 解决. 否则时不时的报错,存储过程名长一点也报错,又有时报有时不报,参数传1位数就正常2位数就报错等…… 折腾mysql蛋疼啊

  2. Delphi笔记(GL_Scene安装及简单使用)

    前一段时间,需要弄一个四轴的监控平台,看了匿名的上位机后,十分感兴趣.于是我也想自己也弄一个上位机来玩玩,在将串口通讯调好了以后,就开始好奇那个3D模型是怎么弄的.在网上面查找了很多资料,由于我用的是 ...

  3. TCP回射服务器程序:str_echo函数

    str_echo函数执行处理每个客户的服务: 从客户读入数据,并把它们回射给客户 读入缓冲区并回射其中内容: read函数从套接字读入数据,writen函数把其中内容回射给客户 如果客户关闭连接,那么 ...

  4. readn、write、readline

    字节流套接字上的read和write函数所表现的行为不同于通常的文件IO 字节流套接字上调用read或write输入或输出的字节数可能比请求的数量少,然而这不是出错的状态 这个现象的原因在于内核中用于 ...

  5. Skynet:特性收集

    基于云风的 blog,收集 skynet 的特性以便将来在代码中一一验证. “ ... ” 部分节选自云风的 BLOG. 1. 基于 Erlang-Actor 模式的 C 实现 “把一个符合规范的 C ...

  6. C# 部分关键字

    关键字: virtual:  虚方法,本身可以被实例化,也可以在派生类中重写该方法: override:在派生类重写基类虚方法时声明,避免了C++中的潜在运行错误: abstract:声明为抽象类.抽 ...

  7. cf C. New Year Ratings Change

    http://codeforces.com/contest/379/problem/C 思路:先排序,然后判断如果rating>ans,ans=rating否则ans++;然后对应的位置输出就可 ...

  8. zoj 1010 Area【线段相交问题】

    链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1010 http://acm.hust.edu.cn/vjudge/ ...

  9. Linux&shell之如何控制脚本

    写在前面:案例.常用.归类.解释说明.(By Jim) Ctrl+C组合键可以生产SIGINT信号Ctrl+Z组合键生产SIGTSTP信号,停止进程后程序仍然留在内存中,能够从停止的地方继续运行. 捕 ...

  10. POJ2242 The Circumference of the Circle(几何)

    题目链接. 题目大意: 给定三个点,即一个任意三角形,求外接圆的周长. 分析: 外接圆的半径可以通过公式求得(2*r = a/sinA = b/sinB = c/sinC),然后直接求周长. 注意: ...