在python的世界當中,try...except...finally語句(statement)可以由with...as語句來替代。
grammar:
with expression as variable:
with一開始執行時(尚未執行expression),會執行__enter__()方法,而該方法所回傳的物件,可以使用as指令給另一個變數來參考(如果有的話),接著執行with區塊內的expression程式碼。
2013年5月17日 星期五
Python的yield
先從Python Official Documentation看起對於yield的解釋
Python 2.7.5 version definition (python2.7.5好像還是視yield為statement?????)
6.8. The yield statement
yield_stmt ::= yield_expression
The yield statement is only used when defining a generator function, and is only used in the body of the generator function. Using a yieldstatement in a function definition is sufficient to cause that definition to create a generator function instead of a normal function.
When a generator function is called, it returns an iterator known as a generator iterator, or more commonly, a generator. The body of the generator function is executed by calling the generator’s next() method repeatedly until it raises an exception.
When a yield statement is executed, the state of the generator is frozen and the value of expression_list is returned to next()‘s caller. By “frozen” we mean that all local state is retained, including the current bindings of local variables, the instruction pointer, and the internal evaluation stack: enough information is saved so that the next time next() is invoked, the function can proceed exactly as if the yield statement were just another external call.
As of Python version 2.5, the yield statement is now allowed in the try clause of a try ... finally construct. If the generator is not resumed before it is finalized (by reaching a zero reference count or by being garbage collected), the generator-iterator’s close() method will be called, allowing any pending finally clauses to execute.
For full details of yield semantics, refer to the Yield expressions section.
Note
In Python 2.2, the yield statement was only allowed when the generators feature has been enabled. This __future__ import statement was used to enable the feature:
from __future__ import generators
Generators和yield之間的關係:
'yield'從python2.5開始,由statement轉成expression。而'yield'就像function的return value一樣,能回傳值出來,但本身又不會結束函式的執行(除非已執行到函式結束為止,才會丟exception)。因為yield只是暫時轉換執行的控制權,並回傳值給原本呼叫它的程式(caller),所以才可以利用yield來產生一系列的值,而擁有'yield'的函式 (function)我們稱之為"generator function(生成器函式)",而yield本身就像是generator function的return一樣。
"Yield," however, implies that the transfer of control is temporary and voluntary, and our function expects to regain it in the future.
In Python, "functions" with these capabilities are called
generators, and they're incredibly useful.generators (and the yield statement) were initially introduced to give programmers a more straightforward way to write code responsible for producing a series of values. generatorsare used to generate a series of valuesyieldis like thereturnofgenerator functions- The only other thing
yielddoes is save the "state" of agenerator function - A
generatoris just a special type ofiterator - Like
iterators, we can get the next value from ageneratorusingnext()forgets values by callingnext()implicitly
yield (生成器)好似是個比較難理解的概念.
當這個生成器被執行時.將會回傳一個 itertor.
之後便可以通過 next() 或者是 send(something) 來呼叫
而他執行後會記住上一次的執行結果..之後再繼續執行
再從良葛格筆記看'yield'的解釋:
從Python 2.5開始,yield從陳述句(statement)改為運算式(expression),也就是yield除了「產生」指定的值之外,會有一個運算結果,yield運算結果預設是None,你可以透過產生器的send()方法傳入一個值,這個值就成為yield的運算結果。這給了你一個與產生器溝通的機會。例如:
| >>> def myrange(n): ... x = 0 ... while True: ... val = (yield x) ... if val is not None: ... x = val ... else: ... x += 1 ... if x >= n: ... break... >>> g = myrange(10) >>> next(g)0 >>> next(g)1 >>> next(g)2 >>> g.send(0)0 >>> next(g)1 >>> next(g)2 >>> g.send(5)5 >>> next(g)6 >>> next(g)7 >>> |
Reference:
1. http://openhome.cc/Gossip/Python/YieldGenerator.html2. Improve your Python: 'yield' and 'generator' explained, http://www.jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/
2013年5月16日 星期四
Cinder: cinder/volume/drivers/xenapi/lib.py
in cinder/volume/drivers/xenapi/lib.py (from grizzly version )
XenAPISession
|- ContextAwareSession
|- OpenStackXenAPISession
CompoundOperations
|- NFSOperationsMixIn
https://bitbucket.org/ncupdclab/sameved-cinder/src/2bc06f23ebfa63b95ca68bb0840df51c267208ce/volume/drivers/xenapi/lib.py?at=master
Citrix Xenserver VDI type
| Type: | enum vdi_type | ||||||||||||
| |||||||||||||
| Name: | type | ||||||||||||
| type of the VDI |
http://docs.vmd.citrix.com/XenServer/4.0.1/api/docs/html/browser.html
Python: contextlib - Utilities for with-statement contexts
This module provides utilities for common tasks involving the with statement. For more information see also Context Manager Types and With Statement Context Managers.
http://docs.python.org/2/library/contextlib.html
http://docs.python.org/2/library/contextlib.html
2013年5月15日 星期三
查閱XeAPI當中的session物件以及xenapi物件底下的method
#!/usr/bin/env python
import sys
import XenAPI
import pprint
import inspect
if __name__ == "__main__":
url = sys.argv[1]
username = sys.argv[2]
password = sys.argv[3]
session = XenAPI.Session(url)
session.xenapi.login_with_password(username,password)
print session.__dict__.items()
print session.xenapi.__dict__.items()
root@StorageController:[~/xenapi-test](master) 4h5m $ python vdi-create.py https://ip:443 account password
[('last_login_method', 'login_with_password'), ('_ServerProxy__transport', <xmlrpclib.SafeTransport instance at 0x7f4a7640ccb0>), ('_ServerProxy__handler', '/RPC2'), ('_ServerProxy__host', '<ip>:443'), ('last_login_params', ('<acccount>', '<password>')), ('_ServerProxy__verbose', 0), ('_ServerProxy__allow_none', 1), ('_session', 'OpaqueRef:35bd0f38-b821-af71-eb26-e151370c6337'), ('API_version', '1.8'), ('_ServerProxy__encoding', None), ('transport', None)]
[('_Dispatcher__API_version', '1.8'), ('_Dispatcher__send', <bound method Session.xenapi_request of <ServerProxy for <ip>:443/RPC2>>), ('_Dispatcher__name', None)]
Python: try...except
在python當中,例外處裡(Exception Handling)是用try...except敘述句來完成,不同於C++/Java當中的try...catch語句。但我有時會覺得疑惑except不是有"除此...之外"的意思嗎?!但這裡的except是當及物動詞使用,可以視為"丟出...的例外"的意思。(思維: 因為exception是例外,如果把它動詞化的話except就是"丟出...的例外"的意思)
try:
// Code here to try
except Exception:
// Exception Handling
Reference:
http://docs.python.org/2/tutorial/errors.html
http://caterpillar.onlyfun.net/Gossip/Python/TryRaise.html
Python
try:
// Code here to try
except Exception:
// Exception Handling
raise
再來看看raise的使用,正如在 try 陳述句 中看到的,你可以在raise後接上字串或例外類別名稱,現在已不鼓勵raise字串實例。實際上,raise之後可以接上例外類別名稱、例外實例或不接上任何東西。
當你在raise後接上例外類別時,實際上會以該類別建立實例再丟出,也就是下面兩行程式碼的作用是相同的:
如果在except中使用raise而不接上任何物件,則表示將except比對到的例外實例再度丟出。例如:
如果必要的話,你還可以在except中raise例外時,附上except所比對到的例外實例。例如。
raise from語法,會將from後接上的例外實例,設定給被raise的例外實例之__cause__。例如:
實際上,如果你在except中raise某個例外,則原except所比對到的例外,無論有無使用raise from,都會自動設定給__context__。例如:
當你在raise後接上例外類別時,實際上會以該類別建立實例再丟出,也就是下面兩行程式碼的作用是相同的:
raise EOFError
raise EOFError()
raise EOFError()
如果在except中使用raise而不接上任何物件,則表示將except比對到的例外實例再度丟出。例如:
| >>> try: ... raise EOFError ... except EOFError: ... print('got it') ... raise ... got it Traceback (most recent call last): File "<stdin>", line 2, in <module> EOFError >>> |
如果必要的話,你還可以在except中raise例外時,附上except所比對到的例外實例。例如。
| >>> try: ... raise EOFError ... except EOFError as e: ... print('got it') ... raise IndexError from e ...got it Traceback (most recent call last): File "<stdin>", line 2, in <module> EOFError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<stdin>", line 5, in <module> IndexError >>> |
raise from語法,會將from後接上的例外實例,設定給被raise的例外實例之__cause__。例如:
| >>> try: ... try: ... raise EOFError('XD') ... except EOFError as e: ... print(e.args) ... raise IndexError('Orz') from e ... except IndexError as e: ... print(e.args) ... print(e.__cause__.args) ...('XD',) ('Orz',) ('XD',) >>> |
實際上,如果你在except中raise某個例外,則原except所比對到的例外,無論有無使用raise from,都會自動設定給__context__。例如:
| >>> try: ... try: ... raise EOFError('XD') ... except EOFError as e: ... print(e.args) ... raise IndexError('Orz') from e ... except IndexError as e: ... print(e.args) ... print(e.__cause__.args) ... print(e.__context__.args) ... ('XD',) ('Orz',) ('XD',) ('XD',) >>> |
Reference:
http://docs.python.org/2/tutorial/errors.html
http://caterpillar.onlyfun.net/Gossip/Python/TryRaise.html
Python: logging module
Logging module
logging module可以分成logger、handler、formatter等三大元件。| Level | When it’s used |
|---|---|
| DEBUG | Detailed information, typically of interest only when diagnosing problems. |
| INFO | Confirmation that things are working as expected. |
| WARNING | An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. |
| ERROR | Due to a more serious problem, the software has not been able to perform some function. |
| CRITICAL | A serious error, indicating that the program itself may be unable to continue running. |
| Level | Numeric value |
|---|---|
| CRITICAL | 50 |
| ERROR | 40 |
| WARNING | 30 |
| INFO | 20 |
| DEBUG | 10 |
| NOTSET | 0 |
NOTEST < DEBUG < INFO < WARNING < ERROR < CRITICAL
如果把debug level設置為INFO,則<INFO的log將不會輸出,只有>= INFO的log才會輸出。
Logger.debug(msg [ ,*args [, **kwargs]])
记录DEBUG级别的日志信息。参数msg是信息的格式,args与kwargs分别是格式参数。
- import logging
- logging.basicConfig(filename = os.path.join(os.getcwd(), 'log.txt'), level = logging.DEBUG)
- log = logging.getLogger('root')
- log.debug('%s, %s, %s', *('error', 'debug', 'info'))
- log.debug('%(module)s, %(info)s', {'module': 'log', 'info': 'error'})
Logger.info(msg[ , *args[ , **kwargs] ] )
Logger.warnning(msg[ , *args[ , **kwargs] ] )
Logger.error(msg[ , *args[ , **kwargs] ] )
Logger.critical(msg[ , *args[ , **kwargs] ] )
记录相应级别的日志信息。参数的含义与Logger.debug一样。
logger.conf
qualname
he qualname entry is the hierarchical channel name of the logger, that is to say the name used by the application to get the logger.Reference:
1. python logging module 入門, http://blog.csdn.net/jgood/article/details/4340740
2. http://www.icoding.co/2012/08/logging-html
Python: sys.exc_info()
If no exception is being handled anywhere on the stack, a tuple containing three None values is returned. Otherwise, the values returned are (type, value, traceback). Their meaning is: type gets the exception type of the exception being handled (a class object); value gets the exception parameter (its associated value or the second argument to raise, which is always a class instance if the exception type is a class object); traceback gets a traceback object (see the Reference Manual) which encapsulates the call stack at the point where the exception originally occurred.
If exc_clear() is called, this function will return three None values until either another exception is raised in the current thread or the execution stack returns to a frame where another exception is being handled.
Warning
Assigning the traceback return value to a local variable in a function that is handling an exception will cause a circular reference. This will prevent anything referenced by a local variable in the same function or by the traceback from being garbage collected. Since most functions don’t need access to the traceback, the best solution is to use something like exctype, value = sys.exc_info()[:2] to extract only the exception type and value. If you do need the traceback, make sure to delete it after use (best done with a try ... finally statement) or to call exc_info() in a function that does not itself handle an exception.
Note
Beginning with Python 2.2, such cycles are automatically reclaimed when garbage collection is enabled and they become unreachable, but it remains more efficient to avoid creating cycles.
Reference:
1. http://docs.python.org/2/library/sys.html
Nova rootwrap
使用root wrapper可以让非特权用户以root身份尽可能安全地执行部分操作。nova曾经使用sudoers文件来列出允许执行的特权命令,使用sudo来运行这么命令,但是这样不容易维护,而且不能进行复杂的参数处理,rootwrap就是为了解决这些问题。
使用sudo nova-rootwrap config-file command,而不再是使用sudo command。只需要使用一个通用的sudoers使nova-rootwrap以root身份运行。nova-rootwrap查看配置文件,加载command filters,检查请求的命令是否匹配某个filter,如果匹配就以root身份运行,否则就拒绝请求。
Reference:
2013年5月14日 星期二
Python: _() 的用途
_在Django中是為了i18n(internationalization)的目的,為了將字串轉譯成其他語言。
http://stackoverflow.com/questions/3967231/whats-the-meaning-of-in-python
Python - “_” Argument to functions
In the interactive interpreter _ is used to reference the last returned value
Eg
>>> 2 + 4
6
>>> _ + 4
10
So you can use it as an argument in a function as well
>>> 2 + 4
6
>>> for i in range(_): print(i)
0
1
2
3
4
5
http://stackoverflow.com/questions/10232404/python-argument-to-functions
訂閱:
文章 (Atom)