加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

GIS笔记——Python入门总结

(2015-01-04 21:47:13)
标签:

it

gis

python

语法

脚本

    最近在学Python。以下是一个简短的总结。写这个东西的目的之一在于写代码的时候作参考,免于翻书查语法。不能保证我所写内容的正确性,仅供参考。



类的定义

        class MyClass(object):

            pass

这段代码定义了一个名为MyClass的类,类里没有任何内容。这个类是所谓“新式类”。如果去掉(object)写成

        class MyClass:

            pass

则是一个“经典类”。二者的区别尚不清楚。有人建议所有类都要用新式类

 

实例化一个对象

        my_object MyClass()

这句代码把MyClass类实例化为一个对象,对象名为my_object

 

类的初始化(构造函数)

   Python中构造函数似乎是叫初始化。初始化可以不写,如果写的话则为如下形式。

        class MyClass(object):

        def __init__(self):

            pass

其中init前后各有两个下划线。参数self是必须的,事实上Python类中所有方法的第一个参数都是self,详见下文。

    如果采用这样的初始化方法,则实例化类的时候不需要传入参数,用如下语句即可实例化

        my_object MyClass()

此时初始化方法中的代码将被执行。

    如果需要在构造函数中传入参数,则构造函数应定义如下

        class MyClass(object):

        def __init__(self, a, b, c):

            pass

这个类的实例化则应采用如下方法

        my_object MyClass(xx, yy, zz)

此时初始化方法中的代码将被执行

 

类里的方法

        Class MyClass(object):

        def do_some_thing(self):

            pass

        def do_some_other_thing(self, a, b, c):

            pass

    这段代码定义了类MyClass,类里面有两个方法,分别为do_something()方法和do_some_other_thing()方法。两个方法的参数中,self是默认的参数。Python规定类里所有的方法的第一个参数都应该是self,且调用的时候不需要传入这个参数。也就是说,上面两个方法分别应该以如下方式调用

        my_object MyClass()

        my_object.do_some_thing()

        my_object.do_some_other_thing(xx, yy, zz)

其中xxyyzz是传入的三个参数,分别对应abc

 

类里的属性

    这个还没有摸清,大致有如下几点。

  5.1 总体感觉Python中的属性比较随意。测试表明,可以先把类实例化成对象,然后给对象赋属性。也就是说,属性并不一定写在类里。这事感觉略荒谬。

  5.2 初步的测试表明,在类里,凡是以

        self.some_thing abc

格式使用的变量均被视为类的属性。并且属性使用的时候必须加上self前缀作为引导。

  5.3 如果在类内、方法外定义一个变量,则这个变量是类的变量,而不是严格的属性。如果代码这么写

        class MyClass(object):

        name Jack Class

则这个nameMyClass的变量,这个变量可以在不做实例化的情况下直接使用。换言之,代码可以这样写

        print(MyClass.name)

而不必

        my_object MyClass()

        print(my_object.name)

相应地,调用这个name的时候不需要加self前缀。

    在类内、方法外定义的变量不允许加self前缀。即程序不允许这样写:

        class MyClass(object):

        self.name Jack Class

上面这段程序会报错

  5.4 在方法内使用的变量,如果不加self前缀,则就是一个普通的变量,作用域仅限于这个方法

  5.5 综上,根据一个文档的建议,在Python中如果需要属性的话,尽量在初始化方法里把属性列出来初始化一下,至少能提高代码的可读性。另外,类的初始化方法如果是有参数的,那么这些参数通常是用于计算属性的。

 

类的继承

        class ClassA(MyClass):

        pass

这段代码定义了一个名为ClassA的类,这个类继承了MyClass类。Python也允许多重继承,例如

        class ClassB(MyClass, YourClass):

        pass

ClassB继承了MyClassYourClass两个父类

 

父类的调用

    这个比较复杂,总体来说有以下几点。

  7.1 Python中,只有方法可以继承,属性不继承。

  7.2 对于一个实例化的对象来说,可以直接调用父类的方法。如果子类有同名的方法,则会覆盖父类的相应方法。由于允许多重继承,实测表明,当两个父类有同名方法的时候,会以第一个父类为准。例如

        class ClassB(MyClass, YourClass):

        pass

如果MyClassYourClass有同名方法,则ClassB继承MyClass中的方法。

  7.3 如果要在子类代码里调用父类的方法,对于一个单继承的类,

        class ClassA(MyClass):

        pass

有两种方法可以调用父类。其一,直接用父类名,即在ClassA里写

        MyClass.do_some_thing(self)

即可调用父类MyClass里的do_some_thing()方法。注意这里调用的时候需要写上self。其二,采用super()语法,即写作

        super(ClassA, self).do_some_thing()

同样可以调用父类里的do_some_thing()方法。注意这里不需要写self

  7.4 在多重继承的情况下如果要在子类代码里调用父类的方法,例如

        class ClassB(MyClass, YourClass):

        pass

则方法一同样有效,即可以用

        MyClass.do_some_thing(self)

        YourClass.do_some_other_thing(self)

分别调用两个父类里的方法。方法二也可以运行,写作

        super(ClassB, self).do_some_thing()

但是在多重继承的情况下super语法会有一些问题。从初步的情况来看,如果两个父类都有do_some_thing(),则貌似只会调用第一个父类的方法。从这个例子来说,就是只会调用MyClassdo_some_thing()方法。

  7.5 Python 中,属性是不直接继承的。不管是实例化后的对象,还是在子类代码里调用父类,均不能直接识别父类的属性。这很可能是因为在Python中,属性都是在方法里定义的。子类在继承父类的过程中并没有运行父类的任何方法(父类的初始化方法也不会被运行),因此相应的属性都没有被定义。

    测试表明,如果父类在某个方法里定义了一个属性

        class MyClass(object):

        def do_some_thing(self):

                self.dream have dream

                print(self.dream)

又有子类

        class ClassA(MyClass):

        pass

那么ClassA如果要使用父类的属性dream,就必须先运行父类的方法do_some_thing()。运行这个方法后,父类MyClass的属性dream就会被子类ClassA所继承。不管是实例化后的对象还是在子类代码里调用父类的属性,如果想要使用父类属性的话,必须先运行相应的方法。

    这提醒我们,在Python中如果要使用“属性”这种面向对象特性的话,应当写一个初始化属性的方法。这样在类被继承的时候,子类运行一下父类的属性初始化方法,就可以继承到父类的所有属性了。类的初始化方法好像是理想的属性初始化位置。

    此外测试还表明,如果在类内、方法外定义一个变量,那么这个变量是可以被继承的。但如5.3所说,这样的变量不是严格的属性。

  7.6 关于super()

    前文提到了super方法。网上的资料没有看懂。这个super存在的意义似乎是在复杂的多重继承情况下,如果要调用父类的方法,可能会出现一些方法的运行次序问题,有一些方法可能会被运行多次。更深入的解释没看明白。super通过一些机制来解决这些问题。但是实测表明,super不能解决多个父类的同名方法需要依次运行这个问题。文档建议仅在类的初始化方法里使用super来运行父类的初始化方法。在没有弄清楚的情况下,应当避免使用super,并避免使用复杂的继承关系。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有