Posted onEdited onInBackendDisqus: Symbols count in article: 3.6kReading time ≈3 mins.
参考引用:《Beginning Python - From Novice to Professional Third Edition 2017》 整理笔记:CK
简单抛出一个异常
1 2 3 4 5 6 7 8 9 10
# 指明异常类 >>> raise Exception Traceback (most recent call last): File "<stdin>", line 1, in ? Exception # 指明异常类,外加参数 >>> raise Exception('hyperdrive overload') Traceback (most recent call last): File "<stdin>", line 1, in ? Exception: hyperdrive overload
也可以自定义一个异常类
class SomeCustomException(Exception): pass
为什么需要异常处理:
为什么不用if语句
用try包住代码段可以一次捕获多个异常,用if语句要一个一个写分别处理。
异常处理可以让程序即使发生致命错误也不必退出:
在交互式的程序里,如果发生错误可以重试
1 2 3 4 5 6
try: x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) print(x / y) except ZeroDivisionError: print("The second number can't be zero!")
try: ... 1/0 ... except ZeroDivisionError: ... raise ValueError ... Traceback (most recent call last): File "<stdin>", line 2, in <module> ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "<stdin>", line 4, in <module> ValueError
捕获不同异常分别处理
1 2 3 4 5 6 7 8 9 10 11 12
>>> try: ... x = int(input('Enter the first number: ')) ... y = int(input('Enter the second number: ')) ... print(x / y) ... except ZeroDivisionError: ... print("The second number can't be zero!") ... except TypeError: ... print("That wasn't a number, was it?") ... Enter the first number: 1 Enter the second number: 0 The second number can't be zero!
慢慢感受到跟if statements 相比的优越性了,后面还有!
捕获不同异常同等处理
原理跟第2点差不多,只是多个异常类型写在一个tuple里,这样可以一并处理了。
1 2 3 4 5 6
try: x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) print(x / y) except (ZeroDivisionError, TypeError, NameError): print('Your numbers were bogus ...')
将捕获的异常对象存到一个变量里
这样可以自己决定如何利用这个异常信息
1 2 3 4 5 6
try: x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) print(x / y) except (ZeroDivisionError, TypeError) as e: print(e)
捕获所有异常
虽然可以处理多个异常,但总有可能漏掉某些无法预估的异常,所以except后留空捕获所有异常
1 2 3 4 5 6
try: x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) print(x / y) except: print('Something wrong happened ...')
whileTrue: try: x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) value = x / y print('x / y is', value) except: print('Invalid input. Please try again.') else: break
根据5点,这里捕获一切异常,因此输入x或y的过程中即使Ctrl-C也是无法退出的,会当作非法输入处理⚠️,如果这不是你希望看到的,最好用except Exception as e:
打扫卫生
举了个没什么意义的例子:
1 2 3 4 5 6 7 8
try: x = 1 / 0 except NameError: print("Unknown variable") else: print("That went well!") finally: print('Cleaning up ...')
classAccessRecord(models.Model): name = models.ForeignKey(Webpage,on_delete=models.CASCADE) date = models.DateField(unique=True)
def__str__(self): return str(self.date)
3. 移植
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
root@38c80f8e29c3:/code# python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying sessions.0001_initial... OK
1 2 3 4 5 6 7
root@38c80f8e29c3:/code# python manage.py makemigrations first_app Migrations for 'first_app': first_app/migrations/0001_initial.py - Create model AccessRecord - Create model Topic - Create model Webpage - Add field name to accessrecord
1 2 3 4 5
root@38c80f8e29c3:/code# python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, first_app, sessions Running migrations: Applying first_app.0001_initial... OK
4. 在对应app的admin.py中注册admin将要管理的模块:
1 2 3 4 5 6
from django.contrib import admin from first_app.models import AccessRecord, Topic, Webpage # Register your models here. admin.site.register(AccessRecord) admin.site.register(Topic) admin.site.register(Webpage)
创建超级用户:(“root@38c80f8e29c3:/code” 说明当前主机是容器)
1 2 3 4 5 6
root@38c80f8e29c3:/code# python manage.py createsuperuser Username (leave blank to use 'root'): ck Email address: willxxx@gmail.com Password: Password (again): Superuser created successfully.
import os # Configure settings for project # Need to run this before calling models from application! os.environ.setdefault('DJANGO_SETTINGS_MODULE','first_project.settings')
import django # Import settings django.setup()
import random from first_app.models import Topic,Webpage,AccessRecord from faker import Faker
defadd_topic(): t = Topic.objects.get_or_create(top_name=random.choice(topics))[0] t.save() return t
defpopulate(N=5): ''' Create N Entries of Dates Accessed '''
for entry in range(N):
# Get Topic for Entry top = add_topic()
# Create Fake Data for entry fake_url = fakegen.url() fake_date = fakegen.date() fake_name = fakegen.company()
# Create new Webpage Entry webpg = Webpage.objects.get_or_create(topic=top,url=fake_url,name=fake_name)[0]
# Create Fake Access Record for that page # Could add more of these if you wanted... accRec = AccessRecord.objects.get_or_create(name=webpg,date=fake_date)[0]
if __name__ == '__main__': print("Populating the databases...Please Wait") populate(20) print('Populating Complete')
执行populate_first_app.py
1 2 3
root@c271100f853b:/code# python populate_first_app.py Populating the databases...Please Wait Populating Complete
# +++++++++++ DJANGO +++++++++++ # To use your own django app use code like this: import os import sys # ## assuming your django settings file is at '/home/hustmck/mysite/mysite/settings.py' ## and your manage.py is is at '/home/hustmck/mysite/manage.py' path = '/home/hustmck/QualityHats-Django' if path notin sys.path: sys.path.append(path)