类变量与对象变量
class Robot:
population = 0 #类变量:用类名加点的方式调用
def __init__(self,name):
self.name = name #对象变量 : 只在本类中使用
print("(Initializing{})".format(self.name))
Robot.population += 1
def die(self):
print("{} is being destroyed".format(self.name))
#Robot.population -= 1
self.__class__.population -= 1
if Robot.population == 0:
print("{} was the last one".format(self.name))
else:
print("There are still {:d} robots working".format(Robot.population))
def say_hi(self):
'''来自机器人的真挚问候'''
print('Greetings,my master call me{}'.format(self.name))
@classmethod #类方法
def how_many(cls):
'''打印出当前的人口数量'''
print(cls.population)
#调用
droid1 = Robot('R2-D2')
droid1.say_hi()
droid1.how_many()
droid1 = Robot('C-3PO')
droid1.say_hi()
droid1.how_many()
(InitializingR2-D2)
Greetings,my master call meR2-D2
1
(InitializingC-3PO)
Greetings,my master call meC-3PO
2
#调用die()方法
droid1.die()
droid1.die()
C-3PO is being destroyed
There are still 1 robots working
C-3PO is being destroyed
C-3PO was the last one
#调用机器人数量
Robot.how_many()
0
Robot.say_hi.__doc__ ##方法文档
'来自机器人的真挚问候'
继承
#父类/基类/super类
class SchoolMember:
'''代表任何学校里的成员'''
def __init__(self,name,age):
self.name = name
self.age = age
# print('Initialized SchoolMember:{}'.format(self.name))
def tell(self):
'''告诉我有关我的细节'''
# end = “目的是打印一行并允许下一次打印在同一行继续”
print('Name:"{}" Age:"{}"'.format(self.name,self.age),end = " ")
#子类/派生类
class Teacher(SchoolMember):
'''代表一位老师'''
def __init__(self,name,age,salary):
SchoolMember.__init__(self,name,age)
self.salary = salary
print('Inintialized Teacher:{}'.format(self.name))
def tell(self):
SchoolMember.tell(self)
print('Teacher - Salary:"{:d}"'.format(self.salary))
#子类/派生类
class Student(SchoolMember):
'''代表一位学生'''
def __init__(self,name,age,marks):
# SchoolMember.__init__(self,name,age)
self.name = name
self.age = age
self.marks = marks
print("Initalized Student : {}".format(self.name))
def tell(self):
SchoolMember.tell(self)
print('Student - Marks {}'.format(self.marks))
t = Teacher("老师1号",30,30000)
s = Student('学生1号',15,75)
Inintialized Teacher:老师1号
Initalized Student : 学生1号
members = [t,s]
for member in members:
member.tell()
Name:"老师1号" Age:"30"
Teacher - Salary:"30000"
Name:"学生1号" Age:"15"
Student - Marks 75
输入与输出
s = input() #用户输入
#width -- 指定填充指定字符后中字符串的总长度.
#fillchar -- 填充的字符,默认为空格。
print("s---" + s.rjust(10,"#")) #补上9个# 长度凑10
input == 1
s---#########1
“创建、读取与写入文件”
def reverse(text):
print('text == '+ text)
print('倒序text == ' + text[::-1])
return text[::-1] #倒叙排列
def is_palindrome(text):
return text == reverse(text)
something = input("Enter text")
if is_palindrome(something):
print("Yes,it's a palindrome")
else:
print("No. it's not a palondrome")
Enter textabcba
text == abcba
倒序text == abcba
Yes,it's a palindrome
#练习 去掉标点
str1 = "Rise to vote, sir"
str2 = ""
list1 = str1[:]
for chars in list1:
if chars not in (",",".","...","?","!"):
str2 += chars
print (str2)
Rise to vote sir
文件的读取/写入
- r - 读取
- w - 写入会覆盖原有内容
- a - 追加
- t - 文本模式
- b - 二进制模式
poem ='''Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!'''
#打开文件以编辑 w - write
f = open('/Users/name/Desktop/Podfile.text','w')
#向文件中编写文本
f.write(poem)
#关闭文件
f.close()
#默认是读 r - read
f1 = open('/Users/name/Desktop/Podfile.text')
while True:
line = f1.readline()
#零长度只是说明已经到了末尾
if len(line) == 0:
break
print (line,end = " ")
f1.close()
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!
Pickle
- “可以将任何纯 Python 对象存储到一个文件中,并在稍后将其取回”
- “持久地(Persistently)存储对象”
import pickle
shoplistfile = '/Users/name/Desktop/Podfile.text'
shoplist = ['apple','mango','carrot']
# 'wb' - 写入二进制文件
p = open(shoplistfile,'wb')
pickle.dump(shoplist,p)
f.close()
del shoplist
# 'rb' - 读取二进制文件
p = open(shoplistfile,'rb')
storedlist = pickle.load(p)
print(storedlist)
['apple', 'mango', 'carrot']
Unicode
import io
uf = io.open('/Users/name/Desktop/Podfile.text','wt',encoding='utf-8')
uf.write(u'Imagine non-English language here')
uf.close()
text = io.open('/Users/name/Desktop/Podfile.text',encoding='utf-8').read()
print(text)
Imagine non-English language here
异常
try:
text = input('Enter something -->')
except EoFError:
print('Why did you do an EOF on me?')
except KeyboardInterrupt:
print('You cancelled the operation')
else:
print('You entered{}'.format(text))
Enter something -->
You entered
抛出异常 521512625218_.pic.jpg
- 通过
raise
语句来引发一次异常,具体方法是提供错误名或异常名以及要抛出(Thrown)异常的对象。 - “你能够引发的错误或异常必须是直接或间接从属于 Exception(异常) 类的派生类。”
class ShortInputException(Exception):
'''一个由用户定义的异常类'''
def __init__(self,length,atleast):
Exception.__init__(self)
#输入文字长度
self.length = length
#“期望的最小长度”
self.atleast = atleast
try:
text = input('Enter something -->')
if len(text) < 3:
raise ShortInputException(len(text),3)
# 其他工作能在此处继续正常运行”
except EOFError:
print('Why did you do an EOF on me?')
except ShortInputException as ex:
print(('ShortInputException: The input was ' + '{0} long, expected at least {1}').format(ex.length, ex.atleast))
else:
print('No exception was raised')
Enter something -->abc
No exception was raised
Try ... Finally
- “确保文件对象被正确关闭”
import sys,time
tf = None
try:
tf = open('/Users/name/Desktop/Podfile.text')
while True:
line = tf.readline()
if len(line) == 0 :
break
print (line, end = "")
#立即打印到屏幕上
sys.stdout.flush()
print('Press ctrl + c Now')
time.sleep(2)
except IOError:
print("Could not find file poem.txt")
except KeyboardInterrupt:
print("!! You cancelled the reading from the file.")
finally:#无论何种错误都会执行关闭 释放资源
if tf:
tf.close()
print("(Cleaning up: Closed the file)")
Imagine non-English language herePress ctrl + c Now
(Cleaning up: Closed the file)
with 语句
- 释放/关闭文件的操作交给 with open 自动完成
with open('/Users/name/Desktop/Podfile.text') as wf:
for line in wf:
print(line,end="")
Imagine non-English language here
传递元组
- 当一个函数中返回两个不同的值时,就会直接返回一个元组
def get_errir_details():
return(2,'details')
errnum,errstr = get_errir_details()
print('errnum== '+ str(errnum))
print('errstr== '+ errstr)
errnum== 2
errstr== details
交换两个变量的最快方法
a = 5
b = 8
a,b = b,a
a,b
(8, 5)
特殊方法
-
__init__(self, ...)
在新创建的对象被返回准备使用时被调用 -
__del__(self)
这一方法在对象被删除之前调用(它的使用时机不可预测,所以避免使用它) -
__str__(self)
当我们使用 print 函数时,或 str() 被使用时就会被调用 -
__lt__(self, other)
当小于运算符(<)被使用时被调用。类似地,使用其它所有运算符(+、> 等等)时都会有特殊方法被调用. -
__getitem__(self, key)
使用 x[key] 索引操作时会被调用 -
__len__(self)
当针对序列对象使用内置 len() 函数时会被调用
函数接受可变参数 - 参数数目不确定
- 参数前加一个 * ,函数的所有其它的额外参数都将传递到 args 中,并作为一个元组予以储存
- 参数前加两个 * ,额外的参数将被视为字典的键值—值配对
def powersum(power, *args):
'''Return the sum of each argument raised to the specified power.'''
total = 0
for i in args:
total += pow(i, power)
return total
print(powersum(2, 3, 4))
print(powersum(2, 10))
25
100
assert 语句 -- 断言
-
如果没有特别的目的,断言应该用于如下情况:
- 防御性的编程
- 运行时对程序逻辑的检测
- 合约性检查(比如前置条件,后置条件)
- 程序中的常量
- 检查文档
-
assert 语句用以断言(Assert)某事是真的
-
大多数情况下,它好过捕获异常,也好过定位问题或向用户显示错误信息然后退出。
-
当语句断言失败时,将会抛出 AssertionError。
mylist = ['item']
assert len(mylist) >= 1
mylist.pop()
'item'
assert len(mylist) >= 1
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-110-0061aada0cbf> in <module>()
----> 1 assert len(mylist) >= 1
AssertionError:
class Account(object):
def __init__(self,number):
self.number = number
self.balance = 0
def deposit(self,amount):
assert amount>0
self.balance += balance
def withdraw(self,amount):
assert amount>0
if amount <= self.balance:
self.balance -= amount
else:
print('balance is not enough')
if __name__ == "__main__":
a = Account(1000)
a.deposit(-10)
程序中,deposit()和withdraw()方法的参数 amount 值必须大于0的,这就是断言的作用,不满足就报错。
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-9-4ed7ce52d5ce> in <module>()
14 if __name__ == "__main__":
15 a = Account(1000)
---> 16 a.deposit(-10)
<ipython-input-9-4ed7ce52d5ce> in deposit(self, amount)
4 self.balance = 0
5 def deposit(self,amount):
----> 6 assert amount>0
7 self.balance += balance
8 def withdraw(self,amount):
AssertionError:
装饰器
- 应用包装函数的快捷方式
- 这有助于将某一功能与一些代码一遍又一遍地“包装”
from time import sleep
from functools import wraps
import logging
logging.basicConfig()
log = logging.getLogger('retry')
def retry(f):
@wraps(f)
def wrapped_f(*args,**kwargs):
MAX_ATTEMPTS = 5
for attempt in range(1, MAX_ATTEMPTS + 1):
try:
return f(*args, **kwargs)
except:
log.exception("Attempt %s/%s failed : %s",
attempt,
MAX_ATTEMPTS,
(args, kwargs))
sleep(10 * attempt)
log.critical("All %s attempts failed : %s",
MAX_ATTEMPTS,
(args, kwargs))
return wrapped_f
counter = 0
@retry
def save_to_database(arg):
print("Write to a database or make a network call or etc.")
print("This will be automatically retried if exception is thrown.")
global counter
counter += 1
# 这将在第一次调用时抛出异常
# 在第二次运行时将正常工作(也就是重试)
if counter < 2:
raise ValueError(arg)
if __name__ == '__main__':
save_to_database("Some bad value")
ERROR:retry:Attempt 1/5 failed : (('Some bad value',), {})
Traceback (most recent call last):
File "<ipython-input-1-dbbe5f071215>", line 14, in wrapped_f
return f(*args, **kwargs)
File "<ipython-input-1-dbbe5f071215>", line 37, in save_to_database
raise ValueError(arg)
ValueError: Some bad value
Write to a database or make a network call or etc.
This will be automatically retried if exception is thrown.
Write to a database or make a network call or etc.
This will be automatically retried if exception is thrown.
网友评论