前言
本文的加法实现代码可以有更简单的方法,只不过为了多讲解点基础知识,故意弄复杂了。
初学python的同学对往往会淹没在纷繁复杂的基础中,不知道学那些基础有什么用,看大型项目的代码的时候往往不知所云。这里就以一个简单的例子来说下大型项目开发的过程。(以后会一直更新)
python调用不同文件下的函数甚至调用不同目录下文件的函数是开始写大规模python代码的前提,本文就python调用函数来做下说明
暂且就当是个项目吧,叫add加法器项目,麻雀虽小,五脏俱全,以后会逐步增加代码。
python函数调用
写好的python项目的目录结构
tree /python
/python/
├── call.py
└── class1_test
├── __init__.py
├── __init__.pyc
├── jisuan.py
└── jisuan.pyc
1 directory, 5 files
各个文件内的代码
cat >/python/class1_test/jisuan.py << EOF
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
def add(*args):
list1=[]
list1.extend(list(args))
total=0
for j in range(0,len(list1)):
total = total+list1[j]
print('{}相加元素和为{}'.format([list1],total))
EOF
class1_test/jisuan.py代码涉及的知识点:
1、extend函数表示追加一个列表到另外一个列表,如果用append方法,只会追加一个列表的整体到另外一个列表而作为另外一个列表的元素。并且如果用append方法,这里就需要用for循环去遍历所有元素再加入另外一个列表,还会带来意想不到的复杂性,不过对于夯实基础很有用(这总方法参考我的另外一篇博文Python列表方法和循环语句组合)。
2、函数的*args表示的是传入一个元组,所以需要用list方法去转化成列表。
3、range函数为左开右闭区间。
cat > /python/call.py << EOF
#!/usr/bin/env python
#coding:utf8
from class1_test.jisuan import add
add(1,2)
EOF
说明:python调用不同目录下文件内函数的方法不止这一种,另外的方法需要导入sys模块(python自带的)。这里不再演示。
运行
python /python/call.py
调用函数语法
方法1
from class1_test.jisuan import add
add(参数1,参数2,参数3...)
from class1_test.jisuan import *
add(参数1,参数2,参数3...)
说明:*表示调用文件内的所有函数。
方法2
import class1_test.jisuan
class1_test.jisuan.add(参数1,参数2,参数3...)
注意:1、import最多能追踪到文件名字,文件里的函数不可以追踪到,如果写成import class1_test.jisuan.add会报错。
2、如果文件中有两行from * import * 代码,如下,默认会执行第二行的调用。
#!/usr/bin/env python
#coding:utf8
from class1_test.jisuan import *
from class1_test.jisuan2 import *
add(参数1,参数2,参数3,...)
并且jisuan和jisuan2中都有函数
cat /python/class1_test/jisuan.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
class Calculate:
def __init__(self,*args):
self.args=args
def add(self,*args):
list1=[]
total=0
for i in args:
list1.append(i)
for j in range(0,len(list1)):
total = total+list1[j]
print('{}相加元素和为{}'.format([list1],total))
[root@ceph01 python]# cat /python/class1_test/jisuan2.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
def add(self,*args):
list1=[]
total=0
for i in args:
list1.append(i)
for j in range(0,len(list1)):
total = total+list1[j]
print('{}相加元素和为{}'.format([list1],total))
调用函数注意事项
1、被调用函数的文件所在目录以及中间途径的各个目录中必须有一个__init__.py文件,这个文件可以为空。
2、被调用函数的文件所在目录名以及中间途径的各个目录名不能是*-*这种形式,比如class-test,并且不能以class命名。
python类调用
写好的python项目的目录结构
tree /python/
/python/
├── bak
├── call.py
└── class1_test
├── bak
│ ├── jisuan2.py
│ ├── jisuan2.pyc
│ ├── jisuan3.py
│ ├── jisuan3.pyc
│ ├── jisuan.py
│ └── jisuan.py.bak
├── __init__.py
├── __init__.pyc
├── jisuan.py
└── jisuan.pyc
3 directories, 11 files
说明:bak目录下为调试代码,和项目无关。
各个文件的代码
cat /python/class1_test/jisuan.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
class Calculate:
def __init__(self,*args):
self.args=args
def add(self,*args):
list1=[]
list1.extend(list(args))
total=0
for j in range(0,len(list1)):
total = total+list1[j]
print('{}相加元素和为{}'.format([list1],total))
cat /python/call.py
#!/usr/bin/env python
#coding:utf8
from class1_test.jisuan import *
c=Calculate()
c.add(1)
c.add(1,2)
c.add(1,2,3)
c.add(1,2,3,4)
c.add(1,2,3,4,5)
b=Calculate(1,2,3,4,5,6)
b.add()
运行
python /python/call.py
运行结果
[[1]]相加元素和为1
[[1, 2]]相加元素和为3
[[1, 2, 3]]相加元素和为6
[[1, 2, 3, 4]]相加元素和为10
[[1, 2, 3, 4, 5]]相加元素和为15
[[]]相加元素和为0
注意:call.py文件最后两行b=Calculate(1,2,3,4,5,6),b.add(),这样实例化并调用对象中的函数,传入的参数为空。
调用类语法
from class1_test.jisuan import *
c=Calculate()
c.add(参数1,参数2,参数3...)
注意:
1、如果文件中有两行from * import * 代码,如下
#!/usr/bin/env python
#coding:utf8
from class1_test.jisuan import *
from class1_test.jisuan2 import *
c=Calculate()
c.add(参数1,参数2,参数3,...)
并且jisuan和jisuan2中都有类Calculate,如下,默认会执行第二行的调用。
cat jisuan.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
class Calculate:
def __init__(self,*args):
self.args=args
def add(self,*args):
list1=[]
list1.extend(list(args))
total=0
for j in range(0,len(list1)):
total = total+list1[j]
print('{}相加元素和为{}'.format([list1],total))
[root@ceph01 class1_test]# cat jisuan2.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
class Calculate:
def __init__(self,*args):
self.args=args
def add(self,*args):
list1=[]
total=0
for i in args:
list1.append(i)
for j in range(0,len(list1)):
total = total+list1[j]
print('{}相加元素和为{}'.format([list1],total))
2、如果文件中有两行from * import * 代码,如下
#!/usr/bin/env python
#coding:utf8
from class1_test.jisuan import *
from class1_test.jisuan2 import *
c=Calculate()
c.add(参数1,参数2,参数3,...)
add(参数1,参数2,参数3,...)
jisuan中有类Calculate,jisuan2中有函数add,如下,会自动识别分别执行各自的调用。
cat /python/class1_test/jisuan.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
class Calculate:
def __init__(self,*args):
self.args=args
def add(self,*args):
list1=[]
total=0
for i in args:
list1.append(i)
for j in range(0,len(list1)):
total = total+list1[j]
print('{}相加元素和为{}'.format([list1],total))
cat /python/class1_test/jisuan2.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
def add(self,*args):
list1=[]
total=0
for i in args:
list1.append(i)
for j in range(0,len(list1)):
total = total+list1[j]
print('{}相加元素和为{}'.format([list1],total))
调用类注意事项
1、类和函数不同的是,要先实例化类,代码中c=Calculate()就是实例化类。
2、被调用类的文件所在目录以及中间途径的各个目录中必须有一个__init__.py文件,这个文件可以为空。
3、被调用类的文件所在目录名以及中间途径的各个目录名不能是*-*这种形式,比如class-test,并且不能以class命名。
配置文件调用
一般大型项目都会有配置文件,用以灵活配置传入的参数,这里就代码怎么调用配置文件做讲解。
写好的python项目的目录结构
tree /python/
/python/
├── bak
├── call.py
├── class1_test
│ ├── bak
│ │ ├── Calculate2.py
│ │ ├── Calculate.py
│ │ ├── jisuan-complex.py
│ │ ├── jisuan.py
│ │ └── jisuan-simple.py
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── jisuan.py
│ └── jisuan.pyc
└── conf
├── add.conf
├── __init__.py
├── __init__.pyc
└── sources
├── __init__.py
├── __init__.pyc
├── readconfig.py
└── readconfig.pyc
5 directories, 17 files
说明:bak目录下为调试代码,和项目无关。
各个文件的代码
cat /python/class1_test/jisuan.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
class Calculate:
def __init__(self,*args):
self.args=args
def add(self,*args):
list1=[]
list1.extend(list(args))
total=0
for j in range(0,len(list1)):
total = total+list1[j]
print('{}相加元素和为{}'.format([list1],total))
cat /python/call.py
#!/usr/bin/env python
#coding:utf8
from class1_test.jisuan import *
#from class1_test.jisuan2 import *
from conf.sources.readconfig import add1
#tuple1=tuple(add)
c=Calculate()
#打印获得的配置文件中的值
print(add1)
#打印获得的配置文件中的值的类型
print(type(add1))
#将获得的配置文件中的值做数据类型的转换
val = eval(add1)
c.add(*val)
cat /python/conf/sources/readconfig.py
#!/usr/bin/env python
# -*- coding:utf8 -*-
import configparser
cf = configparser.ConfigParser()
# 读取配置文件,如果写文件的绝对路径,就可以不用os模块
cf.read("/python/conf/add.conf")
# 获取文件中所有的section(一个配置文件中可以有多个配置,如数据库相关的配置,邮箱相关的配置,
#secs = cf.sections()
#print(secs)
# 获取某个section名为Mysql-Database所对应的键
#options = cf.options("Mysql-Database")
#print(options)
# 获取section名为Mysql-Database所对应的全部键值对
#items = cf.items("Mysql-Database")
#print(items)
# 获取[Mysql-Database]中host对应的值
add1 = cf.get("add", "digital")
cat /python/conf/add.conf
[add]
digital=1,2,3,4
add.conf是不是有openstack配置文件的样子。
cat /python/call.py
#!/usr/bin/env python
#coding:utf8
from class1_test.jisuan import *
#from class1_test.jisuan2 import *
from conf.sources.readconfig import add1
#tuple1=tuple(add)
c=Calculate()
#打印获得的配置文件中的值
print(add1)
#打印获得的配置文件中的值的类型
print(type(add1))
#将获得的配置文件中的值做数据类型的转换
val = eval(add1)
c.add(*val)
运行
python /python/call.py
1,2,3,4
<type 'unicode'>
[[1, 2, 3, 4]]相加元素和为10
调用配置文件语法
#!/usr/bin/env python
#coding:utf8
from conf.sources.readconfig import add1
说明:conf.sources为读取配置文件代码所在目录,readconfig.py为读取配置文件的代码,add1为读取出的配置文件中的[add]标签下digital配置项内容。
调用类注意事项
1、被调用读取配置文件代码所在目录名以及中间途径的各个目录名不能是*-*这种形式,比如class-test,并且不能以class命名。
2、被调用读取配置文件代码所在目录以及中间途径的各个目录中必须有一个__init__.py文件,这个文件可以为空。
运行报错及解决
ll /python/conf/
总用量 4
-rw-r--r--. 1 root root 67 11月 17 16:06 add.conf
drwxr-xr-x. 2 root root 88 11月 17 15:55 sources
Traceback (most recent call last):
File "call.py", line 5, in <module>
from conf.sources.readconfig import add1
ImportError: No module named conf.sources.readconfig
解决
touch /python/conf/__init__.py