以下是小编整理的浅析Lua编程中的异常处理,本文共9篇,欢迎阅读分享,希望对您有所帮助。本文原稿由网友“猫猫头在线发疯”提供。
篇1:浅析Lua编程中的异常处理
这篇文章主要介绍了浅析Lua编程中的异常处理,是Lua入门学习中的基础知识,要的朋友可以参考下
需要进行错误处理
错误处理是必要的,因为真实世界中的操作通常需要使用复杂的操作,包括文件操作,数据库事务和web服务调用,没人关心错误的业务,涉及保密信息或金钱交易时造成大的损失。
在任何编程,总是有错误处理的要求。错误可以是两种类型,其中包括,
语法错误
运行时错误
语法错误
因使用不当造成的各种程序组件,如运算符和表达式中出现语法错误。一个简单的例子中的语法错误如下所示。
代码如下:
a == 2
如你所知,有使用单一等于和双等于之间的差异。使用一个替代其他可导致错误。等于是指分配,比较。同样,表示和有其预定实施这些方式的功能。
另一例为语法错误如下所示。
代码如下:
for a= 1,10
print(a)
end
当我们运行上面的程序,会得到下面的输出。
代码如下:
lua: test2.lua:2: ‘do‘ expected near ‘print‘
语法错误更容易处理程序不是运行时错误,因为,Lua解释更清楚地定位误差比的情况下运行时错误。从上面的错误,我们可以很容易知道,添加do语句之前print语句,每个Lua结构所需要的。
运行时错误
如果运行时错误,程序执行成功,但它可能会导致在输入或处理不当,功能运行时错误是由于错误。一个简单的例子来显示的运行时间误差如下所示。
代码如下:
function add(a,b)
return a+b
end
add(10)
当我们建立的程序,它会成功地建立并运行。一旦运行,它会运行并显示一个运行时错误。
代码如下:
lua: test2.lua:2: attempt to perform. arithmetic on local ‘b‘ (a nil value)
stack traceback:
test2.lua:2: in function ‘add‘
test2.lua:5: in main chunk
[C]: ?
发生因不是通过两个变量的运行时错误。 b参数的预期值是nil,并产生一个错误。
维护和故障功能
为了处理错误时,我们经常使用的两个函数断言和错误。一个简单的例子如下所示。
代码如下:
local function add(a,b)
assert(type(a) == “number”, “a is not a number”)
assert(type(b) == “number”, “b is not a number”)
return a+b
end
add(10)
当我们运行上面的程序,会得到下面的错误输出,
代码如下:
lua: test2.lua:3: b is not a number
stack traceback:
[C]: in function ‘assert‘
test2.lua:3: in function ‘add‘
test2.lua:6: in main chunk
[C]: ?
错误error (message [, level])结束最后一个被叫保护功能,并返回信息的错误消息。这个函数的错误不会返回。通常情况下,错误增加了约在邮件的开头错误位置的一些信息。level参数指定如何得到错误的位置。级别1(默认值),错误位置是误差函数被调用。 2级分错误的地方调用错误的函数被调用等等。传递一个0级可避免增加错误的位置信息的消息。
pcall和xpcall
在 Lua 编程,以避免引发这些错误和处理错误,需要使用的功能 pcall 或 xpcall。
pcall (f, arg1, ...)函数调用保护模式所要求的功能。如果函数f 出现了一些错误,但不会引发错误。它只是返回错误的状态。使用pcall 一个简单的例子如下所示。
代码如下:
function myfunction
n = n/nil
end
if pcall(myfunction) then
print(“Success”)
else
print(“Failure”)
end
当我们运行上面的程序,会得到下面的输出。
代码如下:
Failure
xpcall (f, err) 函数调用所要求的功能,还设置了错误处理程序。f 任何错误不传播; 相反,xpcall 捕获错误,要求与原来的错误对象Err函数,并返回一个状态代码。
一个简单的例子为 xpcall 如下所示。
代码如下:
function myfunction ()
n = n/nil
end
function myerrorhandler( err )
print( “ERROR:”, err )
end
status = xpcall( myfunction, myerrorhandler )
print( status)
当我们运行上面的程序,会得到下面的输出。
代码如下:
ERROR: test2.lua:2: attempt to perform. arithmetic on global ‘n‘ (a nil value)
false
作为一个程序员最重要的是要确保正确的错误处理。使用错误处理可以确保超出边界条件意想不到的条件,而不会干扰该程序的用户进行处理。
篇2:Python编程中的异常处理教程
作者:selFire 字体:[增加 减小] 类型: 时间:-08-21
这篇文章主要介绍了Python编程中的异常处理教程,是Python入门学习中的基础知识,需要的朋友可以参考下
1、异常简介
从软件方面来说,错误是语法或是逻辑上的,当python检测到一个错误时,解释器就会指出当前流已经无法继续执行下去,这时候就出现了异常,异常分为两个阶段:首先是引起异常发生的错误,然后是检测和采取可能的措施。常见异常有
NameError、ZeroDivisionError、SyntaxError、IndexError、KeyError、IOError、AttributeError、ValueError、
TypeError等。所有的标准/内建异常都是从根异常派生的,目前,有3个直接从BaseException派生的异常子类:SystemExit,KeyboardInterrupt和Exception。其它的所有的内建异常都是Exception的子类。
2、异常检测及处理
异常可以通过try语句来检测,有两种主要形式:try-except和try-finally。前者可以添加一个可选的else子句来处理没有检测到异常的情况。一个try语句可以对应一个或多个except语句,但只能对应一个finally子句,except用来捕获并处理异常,可以处理多个异常,也可以指定可选的异常参数(将会是一个包含来自异常的代码的诊断信息的类实例,异常参数自身会组成一个元组,并存储为类实例的属性),要避免裸except(会捕获所有异常,没有机会保存异常发生的原因,虽然可以通过sys.exc_info()获得,但不推荐,如果想捕获所有异常,可以在except中使用BaseException类,而Exception类不包括KeyboardInterrupt和SystemExit),finally无论发生错误与否都会执行。try-except-finally是个复合语句。try检测到异常时,try语句块中的剩余代码是不会执行的,异常会延着堆栈向上提交,直到找到合适的异常处理器,如果到达最顶层仍然没有找到对应的处理器,python解释器会显示出跟踪返回消息,然后退出。
try-except语法如下:
try: try_suite except Exception1[, reason1]: suite_for_exception_ Exception1 except Exception2[, reason2]: suite_for_exception_ Exception2 except (Exception3, Exception4)[, reason3_4]: suite_for_exceptions_ Exception3_and_Exception4 except (Exc5[, Exc6[, ... ExcN]])[, reason]: suite_for_exceptions_ Exc5_to_ExcN else: suite_for_no_exception finally: suite_always_run
可同时捕捉多个异常,可捕捉异常对象,可忽略异常类型以捕捉所有异常
>>>try: x = int(input(‘input x:‘)) y = int(input(‘input y:‘)) print(‘x/y = ‘,x/y) except ZeroDivisionError: #捕捉除0异常 print(“ZeroDivision”) except (TypeError,ValueError) as e: #捕捉多个异常,并将异常对象输出 print(e) except: #捕捉其余类型异常 print(“it‘s still wrong”) input x:12 input y:0 ZeroDivision >>>try: x = int(input(‘input x:‘)) y = int(input(‘input y:‘)) print(‘x/y = ‘,x/y) except ZeroDivisionError: #捕捉除0异常 print(“ZeroDivision”) except (TypeError,ValueError) as e: #捕捉多个异常,并将异常对象输出 print(e) except: #捕捉其余类型异常 print(“it‘s still wrong”) input x:12 input y:y invalid literal for int() with base 10: ‘y‘
try/except 可以加上 else 语句,实现在没有异常时执行什么
>>>try: x = int(input(‘input x:‘)) y = int(input(‘input y:‘)) print(‘x/y = ‘,x/y) except ZeroDivisionError: #捕捉除0异常 print(“ZeroDivision”) except (TypeError,ValueError) as e: #捕捉多个异常 print(e) except: #捕捉其余类型异常 print(“it‘s still wrong”) else: #没有异常时执行 print(‘it work well‘) input x:12 input y:3 x/y = 4.0 it work well
3、上下文管理中的with语句
如上提到的try-except和try-finally,python对隐藏细节做了大量的工作,因此需要你操心的仅是如何解决你所遇到的问题。另一个隐藏低层次的抽象的例子是with语句,它在python2.6中正式启用。python2.5尝试性的引入了with,并对使用with作为标识符的应用程序发出这样的警告――在python2.6中,with将会成为关键字。如果你想在python2.5使用wiht语句,你必须用from __fututure__ import with_statement来导入它。
类似try-except-finally,with语句也是用来简化代码的,这与用try-except和try-finally所想达到的目的千呼后应。try-except和try-finally的一种特定的配合用法是保证共享的资源的唯一分配,并在任务结束的时候释放它。比如文件(数据、日志、数据库等等),线程资源,简单同步,数据库连接等等,with语句的目的就是应用在这种场景,
然而,with语句的目的在于从流程图中把try,except和finally关键字和资源分配释放相关代码统统去掉,而不是像try-except-finally那样仅仅简化代码使之易用。with语法的基本用法如下:
with context_expr [as var]: with_suite
看起来如此简单,但with仅能工作于支持上下文管理协议的对象。当with语句执行时,便执行context_expr来获得一个上下文管理器,其职责是提供一个上下文对象,这是通过调用__context__()方法来实现的。一旦我们获得了上下文对象,就会调用它的__enter__()方法。当with语句块执行结束,会调用上下文对象的__exit__()方法,有三个参数,如果with语句块正常结束,三个参数都是None,如果发生异常,三个参数的值分别等于调用sys.exc_info()函数返回的三个值:类型(异常类),值(异常实例)和回溯(traceback)相应的回溯对象。contextlib模块可以帮助编写对象的上下文管理器。
常见异常:
Exception 所有异常的基类
AttributeError 特性应用或赋值失败时引发
IOError 试图打开不存在的文件时引发
IndexError 在使用序列中不存在的索引时引发
KeyError 在使用映射不存在的键时引发
NameError 在找不到名字(变量)时引发
SyntaxError 在代码为错误形式时引发
TypeError 在内建操作或者函数应用于错误类型的对象是引发
ValueError 在内建操作或者函数应用于正确类型的对象,但是该对象使用不合适的值时引发
ZeroDivisionError 在除法或者摸除操作的第二个参数为0时引发
4.自定义异常:
继承于 Exception 的类
class myException(Exception):pass
5.抛出异常:
raise 语句
>>>def division(x,y): if y == 0 : raise ZeroDivisionError(‘The zero is not allow‘) return x/y >>>try: division(1,0) except ZeroDivisionError as e: print(e) The zero is not allow
6.finally 语句
不管是否出现异常,最后都会执行finally的语句块内容,用于清理工作
所以,你可以在 finally 语句中关闭文件,这样就确保了文件能正常关闭
>>>try: x = int(input(‘input x:‘)) y = int(input(‘input y:‘)) print(‘x/y = ‘,x/y) except ZeroDivisionError: #捕捉除0异常 print(“ZeroDivision”) except (TypeError,ValueError) as e: #捕捉多个异常 print(e) except: #捕捉其余类型异常 print(“it‘s still wrong”) else: #没有异常时执行 print(‘it work well‘) finally: #不管是否有异常都会执行 print(“Cleaning up”) input x:12 input y:3 x/y = 4.0 it work well Cleaning up
异常抛出之后,如果没有被接收,那么程序会抛给它的上一层,比如函数调用的地方,要是还是没有接收,那继续抛出,如果程序最后都没有处理这个异常,那它就丢给操作系统了 -- 你的程序崩溃了,这点和C++一样的。
篇3:Lua中的类编程代码实例
这篇文章主要介绍了Lua中的类编程代码实例,本文直接用代码讲解类的创建、类的实例化、类的方法调用、类的继承、类的多重继承等面向对象编程方法,需要的朋友可以参考下
Lua的类有点像javascript,但是更简明灵活,table即对象,对象就是类,Metatables比起ruby里的MetaClass更加好用,缺点是实例化和继承的代码有点多,
不像ruby里的“<”和“<<”,继承链就是查找方法时的方法链。
Account={ test1=function(a) print(“Account test1”) end}Account.test2=function(a) print(“Account test2”) endfunction Account.test3(a) print(“Account test3”) endfunction Account:new (o) --类的实例化 o = o or {} setmetatable(o, self) self.__index = self return oendfunction Account.print0(o,a) print(a)endfunction Account:print1(a) print(a)end--方法定义测试Account.test1Account.test2()Account.test3()--类测试acc=Account:new()acc.test1()acc.print0(acc,“dot print0”)acc:print0(“not dot print0”)acc.print1(acc,“dot print1”)acc:print1(“not dot print1”)acc.specialMethod=function(specialMethodTest) print(specialMethodTest)endacc.specialMethod(“smt test”)--继承测试SpecialAccount = Account:new()s = SpecialAccount:new{limit=1000.00}--多重继承测试Named = {}function Named:getname () return self.nameendfunction Named:setname (n) self.name = nendlocal function search (k, plist) for i=1, table.getn(plist) do local v = plist[i][k] if v then return v end endendfunction createClass (...) local c = {} -- new class setmetatable(c, {__index = function (t, k) return search(k, arg)end})c.__index = cfunction c:new (o) o = o or {} setmetatable(o, c) return oend return cendNamedAccount = createClass(Account, Named)account = NamedAccount:new{name = “Paul”}print(account:getname())
篇4:Lua面向对象编程学习笔记
这篇文章主要介绍了Lua面向对象编程学习笔记,本文讲解了Lua中实现类的例子、类之间继承的例子等内容,需要的朋友可以参考下
其实 Lua 中的 table 是一种对象,因为它跟对象一样,有其自己的操作方法:
代码如下:
Role = { hp = 100 }
function Role.addHp(hp)
Role.hp = Role.hp + hp
end
Role.addHp(50)
print(Role.hp)
上面代码创建了一个名为 Role 对象,并有一个 addHp 的方法,执行 “Role.addHp” 便可调用 addHp 方法,
不过上面对象 Role 是以全局变量的方式创建,会有一种“全局污染”的威胁,即变量 Role 在其他地方被重新赋值(例如被赋成 nil),对象里的属性或方法可能会面临被销毁或不能正常工作的情况。
对于这种问题,Lua 提供一种“接受者”的解决方法,即额外添加一个参数 self 来表示对象本身:
代码如下:
Role = { hp = 100 }
function Role.addHP(self, hp)
self.hp = self.hp + hp
end
r = Role
r.addHP(r, 50)
print(r.hp)
这样就不怕对象 Role 被“全局污染”,因为构造了一个子对象 r,并以参数的方式传入,以供其方法调用操作。
对于这种把对象本身以参数的方式传入对象方法里的写法,Lua 提供了一种更优雅的写法,把点号(.)替换为冒号(:),这样在方法定义或调用时,便可隐藏 self 参数。修改如下:
代码如下:
Role = { hp = 100 }
function Role:addHp(hp)
self.hp = self.hp + hp
end
r = Role
r:addHp(50)
print(r.hp)
上面的 “r.addHp(50)” 的写法等价于 “r.addHp(r, 50)”
类
Lua 没有类的概念,不过可以通过元表(metatable)来实现与原型 prototype 类似的功能,而 prototype 与类的工作机制一样,都是定义了特定对象行为。Lua 里的原型特性主要使用元表的 __index 事件来实现,这样当调用对象没定义的方法时,会向其元表的 __index 键(事件)查找。例如有 a 和 b 两个对象,想让 b 作为 a 的原型 prototype,只需要把 b 设置为 a 元表的 __index 值就行:
代码如下:
setmetatable(a, {__index = b})
这样,当对象 a 调用任何不存在的成员都会到对象 b 中查找,a 可以拥有或调用 b 的属性或方法,从某种意义上看,b 可以看作是一个类,a 是 b 的对象。
对于上面 Role 的例子,对象的创建可以用 __index 元方法来改写,这样新创建的对象就拥有和 Role 一样的属性和方法。
代码如下:
function Role:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
当执行 “r = Role:new() ” 创建一个对象时,r 将 Role 设置为自己的元表,那么调用 “r:addHp(50)” 的时候,会在 r 里查找 addHp 方法,如果没有找到,则会进一步搜索其元表的 __index,因此等价于:
代码如下:
getmetatable(r).__index.addHp(r, 50)
从上面的 Role:new 方法可以知道,Role 的 __index 在创建时被指定为 self,因此其实就是执行:
代码如下:
Role.addHp(R, 50)
完整的类例子:
代码如下:
Role = { hp = 100 }
function Role:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function Role:addHp(hp)
self.hp = self.hp + hp
end
r = Role:new()
r:addHp(50)
print(r.hp)
继承
Lua 里继承机制还是像实现类那样实现,
假如打算从类 Role 派生出一个子类 Priest,它有一个魔法属性值 mp,那么可以先从类 Role 构造一个 Priest,继承类 Role 的所有属性和方法:
代码如下:
Priest = Role:new()
虽然 Priest 是 Role 的一个实例,不过它具有类 Role 的所有属性和方法,其实也可以把它看做是从类 Role 派生出来的类,因此可以从类 Priest 继续 new 一个对象出来:
代码如下:
p = Priest:new({ mp = 100 })
上面实例 p 除了多出一个魔法属性值 mp 外,还继承类 Role 的所有属性和方法,当调用 “p.addHp” 方法时,Lua 在 p 中找不到 addHp 方法,会到 Priest 中找,在 Priest 中找不到,会到 Role 中找。
因此,想重定义从父类 Role 继承来的方法,在类 Priest 上定义即可。假如想重定义 addHp 方法:每次加血都要先判断魔法值够不够,如果够,则加血,并扣除一定的魔法值。修改如下:
代码如下:
function Priest:addHp(hp)
if self.mp >= 20 then
self.mp = self.mp - 20
self.hp = self.hp + hp
end
end
这样,当调用 “p:addHp” 时,Lua 会优化取类 Priest 定义的 addHp 方法。
篇5:Lua教程(十二):面向对象编程
这篇文章主要介绍了Lua教程(十二):面向对象编程,本文讲解了类、继承、私密性等面向对象编程知识,需要的朋友可以参考下
Lua中的table就是一种对象,但是如果直接使用仍然会存在大量的问题,见如下代码:
代码如下:
Account = {balance = 0}
function Account.withdraw(v)
Account.balance = Account.balance - v
end
--下面是测试调用函数
Account.withdraw(100.00)
在上面的withdraw函数内部依赖了全局变量Account,一旦该变量发生改变,将会导致withdraw不再能正常的工作,如:
代码如下:
a = Account; Account = nil
a.withdraw(100.00) --将会导致访问空nil的错误,
这种行为明显的违反了面向对象封装性和实例独立性。要解决这一问题,我们需要给withdraw函数在添加一个参数self,他等价于Java/C++中的this,见如下修改:
代码如下:
function Account.withdraw(self,v)
self.balance = self.balance - v
end
--下面是基于修改后代码的调用:
a1 = Account; Account = nil
a1.withdraw(a1,100.00) --正常工作。
针对上述问题,Lua提供了一种更为便利的语法,即将点(.)替换为冒号(:),这样可以在定义和调用时均隐藏self参数,如:
代码如下:
function Account:withdraw(v)
self.balance = self.balance - v
end
--调用代码可改为:
a:withdraw(100.00)
1. 类:
Lua在语言上并没有提供面向对象的支持,因此想实现该功能,我们只能通过table来模拟,见如下代码及关键性注释:
代码如下:
--[[
在这段代码中,我们可以将Account视为class的声明,如Java中的:
public class Account
{
public float balance = 0;
public Account(Account o);
public void deposite(float f);
}
--]]
--这里balance是一个公有的成员变量。
Account = {balance = 0}
--new可以视为构造函数
function Account:new(o)
o = o or {} --如果参数中没有提供table,则创建一个空的。
--将新对象实例的metatable指向Account表(类),这样就可以将其视为模板了。
setmetatable(o,self)
--在将Account的__index字段指向自己,以便新对象在访问Account的函数和字段时,可被直接重定向。
self.__index = self
--最后返回构造后的对象实例
return o
end
--deposite被视为Account类的公有成员函数
function Account:deposit(v)
--这里的self表示对象实例本身
self.balance = self.balance + v
end
--下面的代码创建两个Account的对象实例
--通过Account的new方法构造基于该类的示例对象。
a = Account:new
--[[
这里需要具体解释一下,此时由于table a中并没有deposite字段,因此需要重定向到Account,
同时调用Account的deposite方法。在Account.deposite方法中,由于self(a对象)并没有balance
字段,因此在执行self.balance + v时,也需要重定向访问Account中的balance字段,其缺省值为0。
在得到计算结果后,再将该结果直接赋值给a.balance。此后a对象就拥有了自己的balance字段和值。
下次再调用该方法,balance字段的值将完全来自于a对象,而无需在重定向到Account了。
--]]
a:deposit(100.00)
print(a.balance) --输出100
b = Account:new()
b:deposit(200.00)
print(b.balance) --输出200
2. 继承:
继承也是面向对象中一个非常重要的概念,在Lua中我们仍然可以像模拟类那样来进一步实现面向对象中的继承机制,见如下代码及关键性注释:
代码如下:
--需要说明的是,这段代码仅提供和继承相关的注释,和类相关的注释在上面的代码中已经给出。
Account = {balance = 0}
function Account:new(o)
o = o or {}
setmetatable(o,self)
self.__index = self
return o
end
function Account:deposit(v)
self.balance = self.balance + v
end
function Account:withdraw(v)
if v >self.balance then
error(“Insufficient funds”)
end
self.balance = self.balance - v
end
--下面将派生出一个Account的子类,以使客户可以实现透支的功能,
SpecialAccount = Account:new() --此时SpecialAccount仍然为Account的一个对象实例
--派生类SpecialAccount扩展出的方法。
--下面这些SpecialAccount中的方法代码(getLimit/withdraw),一定要位于SpecialAccount被Account构造之后。
function SpecialAccount:getLimit()
--此时的self将为对象实例。
return self.limit or 0
end
--SpecialAccount将为Account的子类,下面的方法withdraw可以视为SpecialAccount
--重写的Account中的withdraw方法,以实现自定义的功能。
function SpecialAccount:withdraw(v)
--此时的self将为对象实例。
if v - self.balance >= self:getLimit() then
error(“Insufficient funds”)
end
self.balance = self.balance - v
end
--在执行下面的new方法时,table s的元表已经是SpecialAccount了,而不再是Account。
s = SpecialAccount:new{limit = 1000.00}
--在调用下面的deposit方法时,由于table s和SpecialAccount均未提供该方法,因此访问的仍然是
--Account的deposit方法。
s:deposit(100)
--此时的withdraw方法将不再是Account中的withdraw方法,而是SpecialAccount中的该方法。
--这是因为Lua先在SpecialAccount(即s的元表)中找到了该方法。
s:withdraw(200.00)
print(s.balance) --输出-100
3. 私密性:
私密性对于面向对象语言来说是不可或缺的,否则将直接破坏对象的封装性。Lua作为一种面向过程的脚本语言,更是没有提供这样的功能,然而和模拟支持类与继承一样,我们仍然可以在Lua中通过特殊的编程技巧来实现它,这里我们应用的是Lua中的闭包函数。该实现方式和前面两个示例中基于元表的方式有着很大的区别,见如下代码示例和关键性注释:
代码如下:
--这里我们需要一个闭包函数作为类的创建工厂
function newAccount(initialBalance)
--这里的self仅仅是一个普通的局部变量,其含义完全不同于前面示例中的self。
--这里之所以使用self作为局部变量名,也是为了方便今后的移植。比如,以后
--如果改为上面的实现方式,这里应用了self就可以降低修改的工作量了。
local self = {balance = initialBalance} --这里我们可以将self视为私有成员变量
local withdraw = function(v) self.balance = self.balance - v end
local deposit = function(v) self.balance = self.balance + v end
local getBalance = function() return self.balance end
--返回对象中包含的字段仅仅为公有方法。事实上,我们通过该种方式,不仅可以实现
--成员变量的私有性,也可以实现方法的私有性,如:
--local privateFunction = function() --do something end
--只要我们不在输出对象中包含该方法的字段即可。
return {withdraw = withdraw, deposit = deposit, getBalance = getBalance}
end
--和前面两个示例不同的是,在调用对象方法时,不再需要self变量,因此我们可以直接使用点(.),
--而不再需要使用冒号(:)操作符了。
accl = newAccount(100.00)
--在函数newAccount返回之后,该函数内的“非局部变量”表self就不再能被外部访问了,只能通过
--该函数返回的对象的方法来操作它们。
accl.withdraw(40.00)
print(acc1.getBalance())
事实上,上面的代码只是给出一个简单的示例,在实际应用中,我们可以将更多的私有变量存放于上例的局部self表中。
篇6:PL/SQL异常处理
在设计PL/SQL程序时,经常会发生这样或那样的错误,异常处理就是针对错误进行处理的程序段,Oracle 9i中的异常处理分为系统预定义异常处理和自定义异常处理两部分,
系统预定义异常处理
系统预定义异常处理是针对PL/SQL程序编译、执行过程中发生的问题进行处理的程序。 下列代码为正确代码,在【SQLPlus Worksheet】中能够顺利执行。
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
set serveroutput on
declare
tempno integer:=90;
begin
tempno:=tempno+1;
end;
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
【配套程序位置】:第9章\\ correctplsql.sql。
下列代码为错误代码,在【SQLPlus Worksheet】中的执行结果如图9.56所示。
【配套程序位置】:第9章\\ wrongplsql.sql。
由于代码有错误,因此将激活系统预定义的异常处理,并得出如下提示信息,
Oracle 9i提供了很多异常处理,读者可以尝试修改可以正常运行的程序,并执行修改后的程序,就可以发现调用了哪些异常处理,下面着重介绍如何自定义异常处理。
自定义异常处理
1.定义异常处理
定义异常处理的语法如下:
declare
异常名 exception;
2.触发异常处理
触发异常处理的语法如下:
raise 异常名;
3.处理异常
触发异常处理后,可以定义异常处理部分,语法如下:
Exception
When 异常名1 then
异常处理语句段1;
When 异常名2 then
异常处理语句段2;
4.实例
下面的PL/SQL程序包含了完整的异常处理定义、触发、处理的过程。定义名为salaryerror的异常,在scott.emp数据表中查找empno=7566的记录,将其值放入变量tempsal中,判断tempsal值若不在900和2600之间,说明该员工的薪水有问题,将激活异常处理,提示信息。
在【SQLPlus Worksheet】中执行下列PL/SQL代码,执行结果如图9.57所示。
【配套程序位置】:第9章\\ exceptiondefine.sql。
篇7:新生儿各种异常情况如何处理
新生儿各种异常情况如何处理 -资料
宝宝从出生那一刻起,就成了家庭的重点呵护对象,其实,有些新生宝宝的异常,并不是病理性的,家长不用过分惊慌,重在处理得当,
1.生理性黄疸
主要是由于胎儿在宫内所处的低氧环境刺激红细胞生成过多,使新生儿早期胆红素的来源较成人多,加之新生儿肝细胞对胆红素的摄取、结合及排泄功能差,故可引起生理性黄疸现象。一般于生后2~3天出现,7~14天消退。一般情况良好,具有自限性,不需治疗,愈后良好。
2.打喷嚏
新生儿偶尔打喷嚏并不是感冒的现象,因为新生儿鼻腔血液的运行较旺盛,鼻腔小且短,若有外界的微小物质如棉絮、绒毛或尘埃等进入便会刺激鼻黏膜引起打嘲,这也可以说是宝宝代替用手自行漓理鼻腔的一种方式。突然遇到冷空气也会打喷嚏。除非宝宝已经流鼻水了,否则家长可以不用担心,也不要动辄让宝宝服用感冒药。
3.脱皮
几乎所有的新生儿都会有脱皮的现象,不论是轻微的皮屑,或是像蛇一样的脱皮,只要宝宝饮食、睡眠都没问题就是正常现象。脱皮是因为新生儿皮肤最上层的角质层发育不完全,容易脱落。
此外,新生儿连表皮和真皮的基底膜并不发达,使表皮和真皮的连接不够紧密,造成表皮脱落的机会增多。这种脱皮的现象全身部位都有可能会出现,但以四肢、耳后较为明显,只要于洗澡时使其自然脱落即可,无须特别采取保护措施或强行将脱皮撕下。若脱皮合并红肿或水泡等其他症状,则可能为病征,需要就诊。
4.新生儿红斑
有的新生儿生后第一天内会出现皮肤普遍发红,并伴有指尖大小的红点。这可能是由于冷而干燥的外界环境及毒素的影响引起的。持续1~2天后逐渐消退,出现脱屑,以足底、足心及皱褶处多见,脱屑完毕后,皮肤呈粉红色。
5.栗粒疹
新生儿的鼻尖,鼻翼及颊部等处常有针尖大小的黄白色点,由皮脂腺堆积所致,称为栗粒疹,而非脓疱,蜕皮后会自然消失。
6.体重减轻
由于出生后最初几天进食较少,同时有不显性失水和大小便排出,故在生后的2~4天内体重有所下降,较刚出生时减轻体重约6%~9%,称之为生理性体重下降。随着奶量的增大,进食增加,约在生后1 O天左右恢复正常,进入快速生长阶段。
7.短暂的窒息
新生儿呼吸的唯一通道是鼻子,虽然较高位置的喉头保证了吸奶时不会意外呛着,但也造成了他无法用嘴呼吸的生理特点,
资料
此外,由于宝宝的肺部还没有发育成熟,有时会有10秒钟左右的“窒息”。不过,6个月后就会正常起来。
8.脱水热
新生儿皮下脂肪薄,体表面积相对较大,容易散热。室温过高时通过皮肤散热增加。如果此时体内水分不足,血液浓缩,易使新生儿发生脱水热。脱水热的热度一般不超过38℃,如能及时发现,补液后可很快降至正常。
9.眼睛斜视
刚出生的宝宝,由于在产道中受过挤压,所以眼睑会有些浮肿,一般2~3天就会消失。一般而言,新生儿早期眼球尚未固定,看起来有点斗鸡眼,而且眼部的肌肉调节不良,常有短暂性的斜视,属于正常生理现象。如果3个月后。宝宝仍旧斜视,应及时带他去医院就诊。
10.乳腺肿大
由于母亲妊娠后期雌激对胎儿的影响,在新生儿出生1周内,不论男孩,女孩都可出现乳腺肿大,可有蚕豆样大小,还可见乳晕颜色增深及泌乳。乳房肿大要在出生后第2~3周才自行消退。有些老人认为女宝宝应该挤出乳汁,使肿大的乳腺恢复正常,同时保证以后妊娠哺乳时有乳汁分泌。这样的做法是错误的,并可能引起感染。
11.频繁打嗝
宝宝出生后的几个月内,一直都有较频繁的打嗝,这是由于横膈膜还未发育成熟。此外,有时打嗝是由于宝宝过于兴奋,有时则是由于刚喂过奶。到了3~4个月的时候,宝宝打嗝就会减少了。若家中的宝宝持续地打嗝一段时间,可以喂宝宝喝一些温开水,以止住打嗝。
12.扁平足
事实上,新生儿足底扁而平是正常的。相反,如果婴儿在头几个月里就有很高的.足弓反而是一种不良的信号,因为它预示着宝宝会有神经或肌肉方面的问题。宝宝到了4~6岁的时候足弓才会发育好。
13. 内八脚和罗圈腿
由于子宫中空间有限,胎儿是以双腿交叉蜷曲,臀部和膝盖拉伸的姿势生长的。因此他的腿、脚向内弯曲。出生后,随着宝宝经常的运动,臀部和腿部的肌肉力量加强。宝宝的身体和脚就会慢慢变直。
14.惊跳
新生儿常在入睡之后有局部的肌肉抽动现象,尤其手指或脚趾会轻轻地颤动。或是受到轻微的刺激如强光、声音或震动等,会表现出双手向上张开,很快又收回,有时还会伴随啼哭、惊跳反应。这是由于新生儿神经系统发育不成熟所致。此时,只要妈妈用手轻轻按住宝宝身体的任何一个部位,就可以使他安静下来。
15.红色尿
新生儿出生后2~5天,由于小便较少,加之白细胞分解较多,使尿酸盐排泄增加,可使尿液呈红色,并在排尿时出现啼哭,多在尿液染红尿布后被发现。此时可加大哺乳量或多喂温开水以增加尿量,防止结晶和栓塞。
篇8:浅谈活性污泥法运行中的异常及处理
浅谈活性污泥法运行中的异常及处理
摘要:活性污泥法是常用的'污水处理工艺,但由于原料和工艺控制等多种原因,使活性污泥在运行中经常会发生一些异常现象,本文探讨了活性污泥法运行中较常见的异常现象及其防治措施.作 者:张影华 作者单位:黑龙江农垦林业职业技术学院,黑龙江,宾西,150431 期 刊:中国科技纵横 Journal:CHINA SCIENCE & TECHNOLOGY PANORAMA MAGAZINE 年,卷(期):, “”(14) 分类号:X7 关键词:活性污泥法 运行 异常现象 措施篇9:程序开发中异常的理解及处理异常论文
程序开发中异常的理解及处理异常论文
从接触异常开始我就弄不明白她,不会用她,想在系统中是异常机制发挥的淋漓尽致,进行了很多尝试,利用异常控制程序流程,利用异常做数字的判断函数,利用异常消除系统中可能出现的恼人的异常提示框,为了更好了利用异常看了很多关于异常的文章,直到有一天看到了一句话——“永远不要去处理你不知道怎么处理的异常”,这才恍然大悟,感觉自己一直在用强大的异常机制干一些旁门左道的是事,更谈不上理解异常在程序中的地位和意义,异常其实一种报告机制,“她以一种不可回避的方式报告程序中所出现的问题”,她帮助程序员走向正确的道路,她忠实的向程序员提供错误报告,她希望有谁能重视并处理掉她报告的问题,哈,真不敢想象,没有了异常机制该如何编制高质量的程序!下面就个人的理解和看法瞎说几句,敬请各位批评指正,不胜感激!异常的工作原理,在有问题的地方产生异常,马上停止当前的工作,转向异常处理代码,如果找不到异常处理代码,就会见异常向一层汇报,上一层接到异常会做同样的事,转向异常处理代码,或者再将异常向上汇报,这样逐层间错误传递出去,直到有一层处理了异常或是一直报告给程序的使用者——用户。这个层就是调用栈,当用户A运行程序B,B从函数C开始执行,调用函数D,再调用函数E,再调用函数F,这时F出现了异常,那么这个异常的调用栈就是A(栈底)—〉B—〉C—〉D—〉E—〉F(栈顶),这个异常就会沿着这个栈从栈顶开始向栈底的方向报告,如果在函数C中有对这个异常的处理代码,那么这个异常的报告链就是F—〉E—〉D—〉C。可以看出,如果在完整的调用栈中没有处理这个异常的代码,用户A就成了异常报告的终点,向windows界面系统,会弹出一个恼人的消息对话框哈。
那么用户A向谁报告呢,哈哈,这个已经不属于程序的范围了,感觉用会对程序而言好像上帝一样,诉说痛苦已经让上帝都听到了,就心满意足了哈哈,看来程序真虔诚哈哈。对于异常这个特性,也可以比喻成下属向上级报告问题,如果下属知情不报,问题就严重了,你要是领导知道下属是这样的八成就踢了他,相反如果你有一个报告机制健全的下属队伍,哈哈你就威风了。日本企业文蛤中有个宗旨——联络,商谈,报告,其实就是想让员工都具有向上级汇报的习惯。现在再看看程序,哈哈,你不用给她们灌输什么企业文化,不用她们讲述什么报告的重要性,她们本身就是忠实报告的,如果把程序员比作企业老总,那么程序就是训练一队有素的`员工。
怎样处理异常。在这里有个原则就是“永远不要去处理你不知道怎么处理的异常”,
也就是只处理你知道如何处理的异常,对那些你不知道的异常必须广开言路,并积极地向上级汇报。什么叫知道如何处理呢?先说一下处理异常有哪些方式,大体有,弹出提示消息框(这个消息框不同于那个恼人的异常报告消息框,她是捕获异常后,根据处理的具体环境程序员主动编写的友好的提示消息框),记录错误日志,吞掉,做善后工作等等,那么出现异常时就要站在出现异常的模块的立场上考虑一下我应该选择哪种处理方式呢?如果不能做出选择就选择不处理,即向上级报告。
举个例子,函数Fun1是创建并返回一个活动的数据连接对象的方法,他接受一个数据库连接字符串,如果调用者(上级)给他一个错误的连接字符串,这时Fun1创建不了连接对象,产生了一个创建不了连接对象的异常,那么这时他应该怎样处理这个异常呢?弹出友好的消息框?说什么友好,Fun1根本就不知道是什么原因使他接收到了错误的连接字符串,弹一个“连接字符串有误”,用户肯定都有杀你的心,这个提示和用户的业务逻辑有嘛关系!记录错误日志,这个还行,但是记录下来的文字无非就是“连接字符串有误,连接字符串是:SQL……”,好点的话,从连接字符串中看出了问题,一般情况下还得根据代码上下文去找问题原因。这个方式不是不行是不好。吞掉,哈哈开什么玩笑,你既创建不了连接,又不吱一声,想让调用者疯了呀,这个肯定不行。做善后工作,行,确实应该清理一下现场,免得浪费资源,但是还是没吱一声,所以这个方式做的不彻底。没招了,哈,其实上面的分析给我们指明了一条路,帮助我们祛除了错误的选择,这条路就是向上汇报,或是不加任何出来代码,或是记录日志,做些善后,再重新将异常抛出。
那么什么时候就知道怎样处理异常了,这就得看实际的情况和用户的要求了,这句话等于没说,就像其他的标题醒目但给出的结论却模棱两可文章一样,哈哈,这里可以给几个建议,
1,一般地,底层模块或是方法中不要处理异常,
2,编写公共模块、DLL等是,不能采用弹出对话框等依赖于平台,框架的方式处理异常,
3,编写公共模块、DLL等时,必须在使用文档中注明每个方法属性可能抛出的异常。
4,永远不要写 try 这样的语句。
{ } catch(Exception) { o nothing } 自定义异常。明白了异常的原理和机制后,就可以自己定义异常了,这样的实践往往在编写控件、公共模块、DLL等的时候,用错误编号在网上搜索一下,能找出一大堆关于错误代码的描述。其中大多数是M(icro)S(oft)制定的,MS 从操作系统到各种各样的框架都有对各种异常的编号,对每种异常做出了详细的定义,如果你还用过像Spread等商业控件,也可以看到他里边的各种各样的异常定义,也就是说我们自己也可以定义异常,在必要的时候,这样就可以让自己写的模块也加入到训练有素的员工队伍中了。至于如何定义异常,具体的编成语言有具体的做法,比如C#中指定一异常一个从Exception继承来的类,VB中异常是个全局变量等等,参见感兴趣语言的语法指南就可以了。
对异常的重新认识,一直以来许多人都认为异常是非常可怕的,可恶的,她是错误的化身,她有恼人的弹出对话框,弄得用户跟凶煞恶神似的哈哈,其实这些都是误解,异常一直默默地忠实的报告着程序中出现的严重的不可回避的问题,她为了程序、系统的正确性、严谨性呼唤你,希望你重视这些问题,希望你用智慧解决这些问题,她是多么的可爱,又是多么的高尚,从来没有因为对她的误解而放弃自己的使命……异常很重要,我们更好学会如何去使用她。
- 编程简历2024-11-06
- 异常的近义词是什么2023-09-20
- 异常报告范文2022-12-13
- Java数据库编程中的几个常用技巧2022-12-18
- 单片机编程个人简历2024-03-28
- 精雕编程个人简历2023-04-05
- JAVA编程简历2025-01-08
- 工作异常报告范文2023-01-07
- 品质异常心得体会范文2022-12-11
- 浅谈变压器中的故障问题处理2023-12-09