模块
使用模块
别名
作用域
使用__future__
面向对象编程
访问限制
继承和多态
获取对象信息
Python例子
模块:一个.py文件就称之为一个模块(Module)
提高了代码的可维护性、避免函数名和变量名冲突。
为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)
举个例子,一个abc.py
的文件就是一个名字叫abc
的模块,一个xyz.py
的文件就是一个名字叫xyz
的模块。
现在,假设我们的abc
和xyz
这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如mycompany
,按照如下目录存放:
引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在,abc.py
模块的名字就变成了mycompany.abc
,类似的,xyz.py
的模块名变成了mycompany.xyz
。
请注意,每一个包目录下面都会有一个__init__.py
的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py
可以是空文件,也可以有Python代码,因为__init__.py
本身就是一个模块,而它的模块名就是mycompany
使用模块:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
' a test module '
import sys
def test():
args = sys.argv
if len(args)==1:
print 'Hello, world!'
elif len(args)==2:
print 'Hello, %s!' % args[1]
else:
print 'Too many arguments!'
if __name__=='__main__':
test()
别名:
导入模块时,还可以使用别名,这样,可以在运行时根据当前环境选择最合适的模块。比如Python标准库一般会提供StringIO
和cStringIO
两个库,这两个库的接口和功能是一样的,但是cStringIO
是C写的,速度更快,所以,你会经常看到这样的写法
try:
import
cStringIO
asStringIO
except ImportError:
# 导入失败会捕获到ImportError
import
StringIO
try:
import
json
# python >= 2.6
except ImportError:
import
simplejson
asjson
# python <= 2.5
作用域:
正常的函数和变量名是公开的(public),可以被直接引用,比如:abc
,x123
,PI
等;
类似__xxx__
这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的__author__
,__name__
就是特殊变量,hello
模块定义的文档注释也可以用特殊变量__doc__
访问,我们自己的变量一般不要用这种变量名;
类似_xxx
和__xxx
这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc
,__abc
等
private函数和变量“不应该”被直接引用,而不是“不能”被直接引用,是因为Python并没有一种方法可以完全限制访问private函数或变量,但是,从编程习惯上不应该引用private函数或变量。
def _private_1(name):
return
'Hello, %s'
% name
def _private_2(name):
return
'Hi, %s'
% name
def greeting(name):
if
len(name) >
3:
return
_private_1(name)
else
:
return
_private_2(name)
我们在模块里公开greeting()
函数,而把内部逻辑用private函数隐藏起来了,这样,调用greeting()
函数不用关心内部的private函数细节,这也是一种非常有用的代码封装和抽象的方法,即:
外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public。
使用__future__
从Python 2.7到Python 3.x就有不兼容的一些改动,比如2.x里的字符串用'xxx'
表示str,Unicode字符串用u'xxx'
表示unicode,而在3.x中,所有字符串都被视为unicode,因此,写u'xxx'
和'xxx'
是完全一致的,而在2.x中以'xxx'
表示的str就必须写成b'xxx'
,以此表示“二进制字符串”。
Python提供了__future__
模块,把下一个新版本的特性导入到当前版本,于是我们就可以在当前版本中测试一些新版本的特性
from __future__ import unicode_literals
print '\'xxx\' is unicode?', isinstance('xxx', unicode)
print 'u\'xxx\' is unicode?', isinstance(u'xxx', unicode)
print '\'xxx\' is str?', isinstance('xxx', str)
print 'b\'xxx\' is str?', isinstance(b'xxx', str)
情况还有除法运算。在Python 2.x中,对于除法有两种情况,如果是整数相除,结果仍是整数,余数会被扔掉,这种除法叫“地板除”: 要做精确除法,必须把其中一个数变成浮点数,而在Python 3.x中,所有的除法都是精确除法,地板除用//
表示
如果你想在Python 2.7的代码中直接使用Python 3.x的除法,可以通过__future__
模块的division
实现:
from __future__ import division
print '10 / 3 =', 10 / 3
print '10.0 / 3 =', 10.0 / 3
print '10 // 3 =', 10 // 3
面向对象编程:
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def print_score(self):
print '%s: %s' % (self.name, self.score)
bart = Student('Bart Simpson', 59)
lisa = Student('Lisa Simpson', 87)
bart.print_score()
lisa.print_score()
访问限制:
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_score(self):
print '%s: %s' % (self.__name, self.__score)
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_score(self, score):
self.__score = score
bart = Student('Bart Simpson', 59)
lisa = Student('Lisa Simpson', 87)
bart.print_score()
lisa.print_score()
print bart.get_name()
print bart.__name
继承和多态:
class Animal(object):
def run(self):
print 'Animal is running...'
class Dog(Animal):
def run(self):
print 'Dog is running'
def eat(self):
print 'Dog is eatting'
class Cat(Animal):
def run(self):
print 'Cat is running'
class Tortoise(Animal):
def run(self):
print 'Tortoise is running slowly...'
def run_twice(animal):
animal.run()
animal.run()
dog=Dog()
dog.run()
cat=Cat()
cat.run()
print isinstance(dog,Animal)
run_twice(dog)
run_twice(Tortoise())
获取对象信息:
import types
print type('abc')==types.StringType
print type(u'abc')==types.UnicodeType
print type([])==types.ListType
print type(str)==types.TypeType
isinstance(
'a', (str, unicode))
isinstance()
判断的是一个对象是否是该类型本身,或者位于该类型的父继承链上。
使用dir():
如果要获得一个对象的所有属性和方法,可以使用dir()
函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:
>>> dir('ABC')
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', '
replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
类似__xxx__
的属性和方法在Python中都是有特殊用途的,比如__len__
方法返回长度。在Python中,如果你调用len()
函数试图获取一个对象的长度,实际上,在len()
函数内部,它自动去调用该对象的__len__()
方法
print len('ABC')
print 'ABC'.__len__()
print 'ABC'.lower()
仅仅把属性和方法列出来是不够的,配合getattr()
、setattr()
以及hasattr()
,我们可以直接操作一个对象的状态
class MyObject(object):
x=0
def __int__(self):
self.x=9
def power(self):
return self.x * self.x
obj=MyObject()
print hasattr(obj,'x')
print hasattr(obj,'y')
setattr(obj,'y',19)
print hasattr(obj,'y')
print getattr(obj,'y')
print obj.y
fn=getattr(obj,'power')
print fn()
Python例子
- 有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数?各是多少?
#!/usr/bin/python
# -*- coding: UTF-8 -*-
for i in range(1, 5):
for j in range(1, 5):
for k in range(1, 5):
if (i != k) and (i != j) and (j != k):
print i, j, k
- 企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数?
#!/usr/bin/python
# -*- coding: UTF-8 -*-
i = int(raw_input('净利润:'))
arr = [1000000, 600000, 400000, 200000, 100000, 0]
rat = [0.01, 0.015, 0.03, 0.05, 0.075, 0.1]
r = 0
for idx in range(0, 6):
if i > arr[idx]:
r += (i - arr[idx]) * rat[idx]
print (i - arr[idx]) * rat[idx]
i = arr[idx]
print r
- 一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
假设该数为 x。
1、则:x + 100 = n2, x + 100 + 168 = m2
2、计算等式:m2 - n2 = (m + n)(m - n) = 168
3、设置: m + n = i,m - n = j,i * j =168,i 和 j 至少一个是偶数
4、可得: m = (i + j) / 2, n = (i - j) / 2,i 和 j 要么都是偶数,要么都是奇数。
5、从 3 和 4 推导可知道,i 与 j 均是大于等于 2 的偶数。
6、由于 i * j = 168, j>=2,则 1 < i < 168 / 2 + 1。
7、接下来将 i 的所有数字循环计算即可。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
for i in range(1, 85):
if 168 % i == 0:
j = 168 / i;
if i > j and (i + j) % 2 == 0 and (i - j) % 2 == 0:
m = (i + j) / 2
n = (i - j) / 2
x = n * n - 100
print(x)
- 输入某年某月某日,判断这一天是这一年的第几天?
分析:以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天,特殊情况,闰年且输入月份大于2时需考虑多加一天
#!/usr/bin/python
# -*- coding: UTF-8 -*-
year = int(raw_input('year:\n'))
month = int(raw_input('month:\n'))
day = int(raw_input('day:\n'))
months = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334)
if 0 < month <= 12:
sum = months[month - 1]
else:
print 'data error'
sum += day
leap = 0
if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
leap = 1
if (leap == 1) and (month > 2):
sum += 1
print 'it is the %dth day.' % sum
- 输入三个整数x,y,z,请把这三个数由小到大输出。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
l = []
for i in range(3):
x = int(raw_input('integer:\n'))
l.append(x)
l.sort()
print l
- 斐波那契数列。
def fib(n):
a, b = 1, 1
for i in range(n - 1):
a, b = b, a + b
return a
# 输出了第10个斐波那契数列
print fib(10)
# 使用递归
def fib(n):
if n == 1 or n == 2:
return 1
return fib(n - 1) + fib(n - 2)
# 输出了第10个斐波那契数列
print fib(10)
55
# -*- coding: UTF-8 -*-
def fib(n):
if n == 1:
return [1]
if n == 2:
return [1, 1]
fibs = [1, 1]
for i in range(2, n):
fibs.append(fibs[-1] + fibs[-2])
return fibs
# 输出前 10 个斐波那契数列
print fib(10)
- 将一个列表的数据复制到另一个列表中
a = [1, 2, 3]
b = a[:]
print b
- 输出 9*9 乘法口诀表。
for i in range(1, 10):
print
for j in range(1, i+1):
print "%d*%d=%d" % (i, j, i*j),
- 暂停一秒输出,并格式化当前时间
import time
print time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
# 暂停一秒
time.sleep(1)
print time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
- 判断101-200之间有多少个素数,并输出所有素数。
- h = 0
leap = 1
from math import sqrt
from sys import stdout
for m in range(101, 201):
k = int(sqrt(m + 1))
for i in range(2, k + 1):
if m % i == 0:
leap = 0
break
if leap == 1:
print '%-4d' % m
h += 1
if h % 10 == 0:
print ''
leap = 1
print 'The total is %d' % h
- (14)