python继承,import总结

继承

  • 先看一段例子:
class Parent():
      def __init__(self, name):
          print "parent, name is %s"%(name)


  class Child(Parent):
      def __init__(self, name):
          super(Child, self).__init__("test")
          print "this is child, name is %s"%(name)

  def main():
      Child("test_child")

  main()

运行此段代码,会报错:

Traceback (most recent call last):
  File "parent.py", line 14, in <module>
    main()
  File "parent.py", line 12, in main
    Child("test_child")
  File "parent.py", line 8, in __init__
    super(Child, self).__init__("test")
TypeError: must be type, not classobj
这是因为python中super只能应用于新类,而不能应用于经典类
所谓新类就是所有类都必须要有继承的类,如果什么都不想继承,就继承到object类

修改后的代码

class Parent(object):
      def __init__(self, name):
          print "parent, name is %s"%(name)


  class Child(Parent):
      def __init__(self, name):
          super(Child, self).__init__("test")
          print "this is child, name is %s"%(name)

  def main():
      Child("test_child")

  main()

让parent继承object类,即可,再次运行:

parent, name is test
this is child, name is test_child

import

  • 先看项目结构:
[wangzijie@kaifa py]$ tree

`-- import_test
    |-- ali
    |   |-- cloud.py
    |   |-- __init__.py
    |   |-- __init__.pyc
    |   |-- taobao
    |   |   |-- __init__.py
    |   |   |-- __init__.pyc
    |   |   |-- taobao.py
    |   |   `-- taobao.pyc
    |   `-- test.py
    |-- baidu
    |   |-- baidu.py
    |   |-- baidu.pyc
    |   |-- __init__.py
    |   `-- __init__.pyc
    |-- __init__.py
    |-- __init__.pyc
    |-- main.py
    `-- tengxun

注意,若想在main中引用taboo.py,必须在Ali和taobao目录都建一个__init__.py的空文件

然后看看main.py:

import ali.taobao.taobao

  def main():
      tb = TaoBao()
      tb.sell()

  main()
import ali.taobao.taobao的意思是导入ali目录下,taobao目录下的taobao.py文件

但是会报错:

Traceback (most recent call last):
  File "main.py", line 7, in <module>
    main()
  File "main.py", line 4, in main
    tb = TaoBao()
NameError: global name 'TaoBao' is not defined

这是因为要使用导入的包中的东西,需要加包的前缀

修改:

import ali.taobao.taobao

  def main():
      tb = taobao.TaoBao()
      tb.sell()

  main()

以上运行:

Traceback (most recent call last):
  File "main.py", line 7, in <module>
    main()
  File "main.py", line 4, in main
    tb = taobao.TaoBao()
NameError: global name 'taobao' is not defined

在golang中,import的包只需要加最后一项就可以了,即taobao;但是python不一样,必需得加全部的import路径

即:

import ali.taobao.taobao

  def main():
      tb = ali.taobao.taobao.TaoBao()
      tb.sell()

  main()

这样可以运行成功,但包名太长,改进,用import ... as的方式为包起别名:

import ali.taobao.taobao as taobao

  def main():
      tb = taobao.TaoBao()
      tb.sell()

  main()

也可以用指定引用某个包下的某个文件的方法:

from ali.taobao import taobao

  def main():
      tb = taobao.TaoBao()
      tb.sell()

  main()

指定import ali包下,taobao包下的taobao.py文件

也可以指定引用taobao文件中的TaoBao类

from ali.taobao.taobao import TaoBao

  def main():
      tb = TaoBao()
      tb.sell()

  main()

这样就不需要加前缀了

总结:from ... import ...,既可以指定引入某个目录下的某个文件,也可以指定引入某个文件中的某个类,函数,变量;

另一个场景

对于这样的目录结构:

.
|-- ali
|   |-- cloud.py
|   |-- __init__.py
|   |-- __init__.pyc
|   `-- taobao
|       |-- __init__.py
|       |-- __init__.pyc
|       |-- taobao.py
|       `-- taobao.pyc
|-- baidu
|   |-- baidu.py
|   |-- baidu.pyc
|   |-- __init__.py
|   `-- __init__.pyc
|-- __init__.py
|-- __init__.pyc
|-- main.py
`-- tengxun

想要在ali/cloud.py中import baidu.py,该如何引入?

看看cloud.py的代码:

from import_test.baidu.baidu import Baidu

  class Ali(object):
      def __init__(self):
          self.partner = Baidu()
          self.partner.show()
          print "init ali"

  def main():
      ali = Ali()

  if __name__ == "__main__":
      main()

直接运行会报错:

Traceback (most recent call last):
  File "cloud.py", line 1, in <module>
    from import_test.baidu.baidu import Baidu
ImportError: No module named import_test.baidu.baidu

这是因为python搜索模块的路径,首先会搜索自带模块,若没有则搜索sys.path;
sys.path首先是脚本执行的位置,然后是PYTHONPATH,最后是安装依赖的位置;

由于baidu.py是自定义的模块,所以应该去sys.path搜索,脚本执行位置肯定无法找到,因此去PYTHONPATH查找;

在启动前加上:

[wangzijie@kaifa]$ PYTHONPATH=/home/wangzijie/dev/test/py/ python cloud.py
init baidu
this is baidu
init ali

即可成功

需要注意,若要引用import_test.baidu.baidu这个模块,必须保证每个包下都有__init__.py文件;

byte
106 声望13 粉丝