天天看点

以魔兽世界为引言,探讨一下python里的类

Python学到类这里就是达到了第一个瓶颈,因为此时程序思考和阅读的路线就不再直观,而是要拐一个弯弯。当突破了这一段就会达到了一个新的高度,但是“类”主要还是应用于多对象的建立,在大程序中为了省事,往往需要“类”的概念。小程序、小脚本可以不使用。

“类”相当于一个“模型”,有了“模型”/“图纸”,才能实例化把抽象的东西成为具体。所以说“类”里的东西要有共性,以著名网游魔兽世界为例,在WOW里的NPC主要分为以下几种:“亡灵(受到神圣攻击伤害大)”、“人类(临死的时候会惊恐的逃跑求助”,“元素(可以被放逐)”,“野兽(可以被驯服恐吓)”等等,这样多种的设定使得面对不同的怪,就可以采用不同针对的方法会有事半功倍的效果。而游戏开发者在编写代码的时候,就可以单独把“人类”做成一个类,下面笔者中英文结合,讲述这个过程,请诸位领会其精神:

     class 人类:

        def 属性1:

         “生命值为0的时候会死亡”

        def 属性2:

          “可以被魅惑”

        def 属性3:

          “生命值下降到20%的时候会逃跑求助”

        def 属性4:

          “基本移动距离为1像素/秒,跑步距离为2像素/秒”

        def 属性5:

          “跳舞的姿势/大笑的姿势/惊恐的姿势/跑火车的姿势....”

        def 属性6:

          “死亡的姿势/跑步的姿势/拿弓箭的姿势/拿长柄武器的姿势/拿双手武器的姿势”

          等等等等,就不一一列举了。

以上这些是作为“人类”这个NPC类的同性,至于在不同的NPC中就由他们自己的细化属性进行细化。比如“血色十字军”,就有他们自己的细化属性,思路过程如下:

    血色十字军=人类()       #血色十字军是属于“人类”这个类的#

    血色十字军.对玩家态度=仇恨  #这是可以击杀的#

    血色十字军.生命值=XXX    #游戏里即使是同一个等级的每一个怪物也血量不同,应该是使用了random模块,然后选择一个范围,从中任意取值#

    血色十字军.喊话=“台词”   #遭到攻击/发现敌人的时候会喊自己独特的台词#

通过这些细节的细化,使“血色十字军”这种NPC得到了进一步的丰满。同时由于怪物也分为战士,圣骑士,牧师等职业,那么还需要再设定“战士”的类,“圣骑士”的类,“牧师”的类,通过“父类--子类”的继承特性,进一步的将怪物丰满到位。

    其他的怪物,比如“石像鬼”和“食尸鬼”都属于“亡灵类”,但是“石像鬼”可以有自己的细化属性,比如“空中远距离攻击+移动的像素更大”,而“食尸鬼”的细化属性是“普通的近距离抓击”等等。

==================================分割线=========================================

以上仅仅是用一个身边的例子来讲述一下“类”的浅显用处,帮助各位理解。下面将探讨一个程序,从这个程序中的输出结果里找到一些“类”的特性。

1

2

3

4

5

6

7

8

9

10

<code>class</code> <code>C:</code>

<code>def</code> <code>__init__(</code><code>self</code><code>,size</code><code>=</code><code>10</code><code>):</code>

<code>self</code><code>.size </code><code>=</code> <code>size</code>

<code>def</code> <code>getSize(</code><code>self</code><code>):</code>

<code>return</code> <code>self</code><code>.size</code>

<code>def</code> <code>setSize(</code><code>self</code><code>,value):</code>

<code>self</code><code>.size </code><code>=</code> <code>value</code>

<code>def</code> <code>delSize(</code><code>self</code><code>):</code>

<code>del</code> <code>self</code><code>.size</code>

<code>x </code><code>=</code> <code>property</code><code>(getSize,setSize,delSize)</code>

全部程序在此,先使用c1=C(),来将这个“图纸”实例化。

    &gt;&gt;&gt;c1.getSize()

    输出结果为10,因为c1已经默认启动了__init__这个函数,size=10这个变量已经进入c1中,由于self的特性,在c1中,生成了c1.size = size =10,故c1.getSize()可以直接return。

    __init__函数是类函数里上来就默认执行的函数,对于本例函数而言,他的操作步骤是这样的:

                  |------&gt;getSize()

    函数启动-----&gt;__init___ |------&gt;setSize()

                 |------&gt;delSize()

    且不要当成普通函数步骤从上往下的看,而是要“主线--分支”的看。

    &gt;&gt;&gt;c1.x

    输出结果为10,这是因为property语句的特性---“以变量规定定义好的变量”,property后面三项有一项有值,就可以返回给x这个属性,然后被c1拿来。注意,这个没有输入上面的c1.getSize(),直接c1.x也是会返回10的,因为已经执行了__init__。

    &gt;&gt;&gt;c1.x=18

    输出结果为18,这个没什么好说的,因为手动已经将c1里的x属性设定为18,自然就会返回18。

    此时的输出结果不再是10,而是18。这是由结果往前推。

    &gt;&gt;&gt;c1.setSize(5)

    此时的输出结果为5,这又是从手动设定的值往结果推。可见属性在“类”里是可以从前到后的变,也可以从后到前的变。注意,type(c1.setSize(5))的结果是&lt;class 'NoneType'&gt;。

    &gt;&gt;&gt;c1.getSize(5)

    此时的输出还是5。印证了刚才的想法,属性的值可以来回的改。

在实际工作中,可以一个一个改前面的项,这样得到一个更改后的x值,也可以通过直接改x的值,一步到位的更改了前面的所有项,而后者是大程序应用里更加简单的方法。

 本文转自 苏幕遮618 51CTO博客,原文链接:http://blog.51cto.com/chenx1242/1728781