2017年4月30日 星期日

[Python 學習筆記] 進階議題 : 例外 (再看 try、raise)

轉載自 這裡
前言 :
except 後若不接上任何例外型態,則表示捕捉所有例外,這包括了所有的系統例外,有時這並不是你想要的行為. 例如,下面這個程式,無法透過 KeyboardInterrup t 來中斷迴圈 :
  1. while True:  
  2.     try:  
  3.         print('Run it....')  
  4.     except:  
  5.          print('exception happened...')  
再看 try、raise :
由於 except 捕捉所有的例外,所以上例無法離開迴圈. 你可以改為以下的方式 :
  1. while True:  
  2.     try:  
  3.         print('Run it....')  
  4.     except Exception:  
  5.          print('exception happened...')  
在 Python 3 中,Exception 是 BaseException 的子類別,可以捕捉除了系統例外以外的所有例外. 上例可以藉由 KeyboardInterrupt 中斷迴圈. 在 Python 3 中,可以在 except 捕捉到例外後,將例外物件指定給變數. 例如 :
  1. try:  
  2.     raise IndexError('11')  
  3. except IndexError as e:  
  4.     print(type(e), str(e))  
Output:
11


在更進階的例外追蹤需求中,可以使用 sys.exc_info() 方法取得一個 Tuple 物件,該 Tuple 物件中包括了 例外的類型、例外訊息 以及 traceback 物件 :
  1. import sys  
  2.   
  3. try:  
  4.     raise 'Error'  
  5. except:  
  6.     a, b, c = sys.exc_info()  
  7.     print(a)  
  8.     print(b)  
  9.     print(c)  
Output:

exceptions must derive from BaseException


trackback 物件代表了呼叫堆疊中每一個層次的追蹤,可以使用 tb_next 取得更深一層的呼叫堆疊. 例如 :
- test1.py :
  1. import sys  
  2. def test():  
  3.     raise EOFError  
  4.   
  5. try:  
  6.     test()  
  7. except:  
  8.     type, message, traceback = sys.exc_info()  
  9.     while traceback:  
  10.         print('--------------')  
  11.         print('type=',type)  
  12.         print('message=', message)  
  13.         print('function or module? ', traceback.tb_frame.f_code.co_name)  
  14.         print('file? ', traceback.tb_frame.f_code.co_filename)  
  15.         traceback = traceback.tb_next  
執行結果 :
--------------
type=
message=
function or module?
file? ./a.py
--------------
type=
message=
function or module? test
file? ./a.py

tb_frame 代表了該層追蹤的所有物件資訊,f_code 可以取得該層的程式碼資訊,例如 co_name 可取得函式或模組名稱,而 co_filename 則表示該程式碼所在的檔案.

再來看看 raise 的使用,正如在 try 陳述句 中看到的,你可以在 raise 後接上字串或例外類別名稱,現在已不鼓勵 raise 字串實例。實際上,raise 之後可以接上例外類別名稱、例外實例或不接上任何東西. 當你在 raise 後接上例外類別時,實際上會以該類別建立實例再丟出,也就是下面兩行程式碼的作用是相同的 :
  1. raise EOFError  
  2. raise EOFError()  
如果在 except 中使用 raise 而不接上任何物件,則表示將 except 比對到的例外實例再度丟出. 例如 :
  1. try:  
  2.     raise EOFError  
  3. except EOFError:  
  4.     print('got it')  
  5.     raise  
Output:
got it
Traceback (most recent call last):
File "./a.py", line 3, in
raise EOFError
EOFError

如果必要的話,你還可以在 except 中 raise 例外時,附上自己的例外到 except 所比對到的例外實例. 例如 :
- test2.py :
  1. try:  
  2.     raise EOFError  
  3. except EOFError as e:  
  4.     print('got it')  
  5.     raise IndexError from e  
執行結果 :
got it
Traceback (most recent call last):
File "./a.py", line 3, in
raise EOFError
EOFError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "./a.py", line 6, in
raise IndexError from e
IndexError

raise from 語法,會將 from 後接上的例外實例,設定給被 raise 的例外實例之 __cause__ . 例如 :
- test3.py :
  1. try:  
  2.     try:  
  3.         raise EOFError('XD')  
  4.     except EOFError as e:  
  5.         print('Except(EOFError): ', e.args)  
  6.         raise IndexError('Orz') from e  
  7. except IndexError as e:  
  8.     print('Except(IndexError): ', e.args)  
  9.     print('\tArgs from cause: ', e.__cause__.args)  
執行結果 :
Except(EOFError): ('XD',)
Except(IndexError): ('Orz',)
Args from cause: ('XD',)

實際上,如果你在 except 中 raise 某個例外,則原 except 所比對到的例外,無論有無使用 raise from,都會自動設定給 __context__ . 例如 :
- test4.py :
  1. try:  
  2.     try:  
  3.         raise EOFError('XD')  
  4.     except EOFError as e:  
  5.         print('Except(EOFError): Args=', e.args)  
  6.         raise IndexError('Orz') from e  
  7. except IndexError as e:  
  8.     print('Except(IndexError): Args=', e.args)  
  9.     print('\te.__cause__.args=', e.__cause__.args)  
  10.     print('\te.__context__.args=', e.__context__.args)  
執行結果 :
Except(EOFError): Args= ('XD',)
Except(IndexError): Args= ('Orz',)
e.__cause__.args= ('XD',)
e.__context__.args= ('XD',)

This message was edited 24 times. Last update was at 30/04/2017 18:57:34

2017年4月29日 星期六

[ Java 代碼範本 ] HttpClient4.x: Making HTTPS call using Apache HttpClient

Source From Here 
Preface 
This post details about making Secure HTTP (HTTPs) call from a server using Apache HTTPClient library

Trust any certificate approach (Simple, not recommended for production code.
The simplest will be to ignore the ssl certificates and to trust any connection. This approach is not acceptable for production code as it defeat the purpose of using HTTPS. However in some use cases if you want to try out something quickly you can go with this route. 
  1. import javax.net.ssl.SSLContext;  
  2. import javax.net.ssl.X509TrustManager;  
  3.   
  4. import org.apache.http.client.HttpClient;  
  5. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;  
  6. import org.apache.http.conn.ssl.SSLContexts;  
  7.   
  8. import org.apache.http.impl.client.CloseableHttpClient;  
  9. import org.apache.http.impl.client.HttpClients;  
  10.   
  11. import java.security.SecureRandom;  
  12.   
  13. public class HttpClientFactory {  
  14.   
  15.     private static CloseableHttpClient client;  
  16.   
  17.     public static HttpClient getHttpsClient() throws Exception {  
  18.   
  19.         if (client != null) {  
  20.             return client;  
  21.         }  
  22.         SSLContext sslcontext = SSLContexts.custom().useSSL().build();  
  23.         sslcontext.init(nullnew X509TrustManager[]{new HttpsTrustManager()}, new SecureRandom());  
  24.         SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,  
  25.                 SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);  
  26.         client = HttpClients.custom().setSSLSocketFactory(factory).build();  
  27.   
  28.         return client;  
  29.     }  
  30.   
  31.     public static void releaseInstance() {  
  32.         client = null;  
  33.     }  
  34. }  
The above method will return httpClient object which can be used to make any HTTPS calls. Performing HTTPS call is no different from making HTTP call from now on. So you can have a factory with two methods, one for secure and one for non-secure. Here we have used HttpsTrustManager, which will do nothing more than trusing all clients. This is done by simply implementing X509TrustManager and auto generating all the methods. 
  1. import java.security.cert.CertificateException;  
  2. import java.security.cert.X509Certificate;  
  3.   
  4. import javax.net.ssl.X509TrustManager;  
  5.   
  6. public class HttpsTrustManager implements X509TrustManager {  
  7.   
  8.     @Override  
  9.     public void checkClientTrusted(X509Certificate[] arg0, String arg1)  
  10.             throws CertificateException {  
  11.         // TODO Auto-generated method stub  
  12.   
  13.     }  
  14.   
  15.     @Override  
  16.     public void checkServerTrusted(X509Certificate[] arg0, String arg1)  
  17.             throws CertificateException {  
  18.         // TODO Auto-generated method stub  
  19.   
  20.     }  
  21.   
  22.     @Override  
  23.     public X509Certificate[] getAcceptedIssuers() {  
  24.         return new X509Certificate[]{};  
  25.     }  
  26.   
  27. }  
Importing a keystore (Recommended
If you are writing produciton quality code, then you should be looking at this approach. Have a all the keys in your application and create a SSLContext using those keystores. The created SSLContext can then be injected to SSLConnectionSocketFactory and remaining steps will be the same. 
  1. import javax.net.ssl.SSLContext;  
  2.   
  3. import org.apache.http.client.HttpClient;  
  4. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;  
  5. import org.apache.http.conn.ssl.SSLContexts;  
  6.   
  7. import org.apache.http.impl.client.CloseableHttpClient;  
  8. import org.apache.http.impl.client.HttpClients;  
  9. import java.io.File;  
  10. import java.io.FileInputStream;  
  11. import java.io.IOException;  
  12. import java.security.KeyStore;  
  13. import java.security.KeyStoreException;  
  14. import java.security.NoSuchAlgorithmException;  
  15. import java.security.cert.CertificateException;  
  16. import java.security.KeyManagementException;  
  17.   
  18. public class HttpClientFactory {  
  19.   
  20.     private static CloseableHttpClient client;  
  21.   
  22.     public static HttpClient getHttpsClient() throws Exception {  
  23.   
  24.         if (client != null) {  
  25.             return client;  
  26.         }  
  27.         SSLContext sslcontext = getSSLContext();  
  28.         SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,  
  29.                 SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);  
  30.         client = HttpClients.custom().setSSLSocketFactory(factory).build();  
  31.   
  32.         return client;  
  33.     }  
  34.   
  35.     public static void releaseInstance() {  
  36.         client = null;  
  37.     }  
  38.   
  39.     private SSLContext getSSLContext() throws KeyStoreException,   
  40.     NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException {  
  41.         KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());  
  42.         FileInputStream instream = new FileInputStream(new File("my.keystore"));  
  43.         try {  
  44.             trustStore.load(instream, "nopassword".toCharArray());  
  45.         } finally {  
  46.             instream.close();  
  47.         }  
  48.         return SSLContexts.custom()  
  49.                 .loadTrustMaterial(trustStore)  
  50.                 .build();  
  51.     }  
  52. }  
The only difference between the two approaches are the way the SSLContext been created.

[ Py DS ] Ch3 - Data Manipulation with Pandas (Part5)

Source From  Here   Pivot Tables   We have seen how the  GroupBy  abstraction lets us explore relationships within a dataset. A pivot ta...