Как модули и метод поиска в Python

#python #python-3.x

#python #python-3.x

Вопрос:

Для среды установки Linux стандартные модули Python в основном хранятся по пути ‘/usr/lib64/python3x/‘ в виде одного файла .py. (Здесь я использую версию 3.6 и Centos 6) Все доступные методы и классы должны быть найдены в этом единственном файле .py.

Возьмем, к примеру, модуль ‘datetime‘, в документах говорится, что у него есть класс с именем ‘date‘, и для этого класса у него есть метод с именем ‘today()‘. Итак, в ‘/usr/lib64/python3.6/datetime.py ‘ мы можем найти

 class date:
..
..
    def today(cls):
    ..
    ..
  

Однако для модуля ‘ssl’ в ‘/usr/lib64/python3.6/ssl.py ‘, в документах есть этот метод, называемый ‘SSLContext.cert_store_stats()‘, но в файле ‘ssl.py ‘, Я могу найти класс SSLContext, но, похоже, я не могу найти метод cert_store_stats() в этом классе. Почему это так?

Это не из-за какой-либо проблемы с кодом, просто из любопытства, как Python ищет свой модуль и метод.

Комментарии:

1. Но это всего лишь стандартное наследование. Этот файл показывает, что SSLContext наследуется от _SSLContext , который является классом, реализованным непосредственно на C в модуле _ssl, и который предоставляет этот метод.

Ответ №1:

Если вы прочитаете ssl.py источник, в самых первых строках говорится:

 # Wrapper module for _ssl, providing some additional facilities
# implemented in Python.
  

Затем немного ниже (после строки документа модуля) вы найдете

 from _ssl import _SSLContext
  

и, наконец, SSLContext определение класса, начинающееся с:

 class SSLContext(_SSLContext):
  

Итак, метод, который вы ищете, унаследован от _ssl._SSLContext .

ПРИМЕЧАНИЕ: _ssl это модуль, закодированный на C, и вы найдете пару других в приложениях stdlib и 3rd part.

Ответ №2:

Как указал @DanielRoseman в комментариях, SLLContext наследуется от _SLLContext в ssl.ply :

 class SSLContext(_SSLContext):
  

И _SLLContext находится в _ssl.c . Если вы посмотрите вокруг, вы можете увидеть, что в _ssl.c _SSLContext.cert_store_stats определено:

 static PyObject *
_ssl__SSLContext_cert_store_stats_impl(PySSLContext *self)
/*[clinic end generated code: output=5f356f4d9cca874d input=eb40dd0f6d0e40cf]*/
{
    X509_STORE *store;
    STACK_OF(X509_OBJECT) *objs;
    X509_OBJECT *obj;
    int x509 = 0, crl = 0, ca = 0, i;

    store = SSL_CTX_get_cert_store(self->ctx);
    objs = X509_STORE_get0_objects(store);
    for (i = 0; i < sk_X509_OBJECT_num(objs); i  ) {
        obj = sk_X509_OBJECT_value(objs, i);
        switch (X509_OBJECT_get_type(obj)) {
            case X509_LU_X509:
                x509  ;
                if (X509_check_ca(X509_OBJECT_get0_X509(obj))) {
                    ca  ;
                }
                break;
            case X509_LU_CRL:
                crl  ;
                break;
            default:
                /* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY.
                 * As far as I can tell they are internal states and never
                 * stored in a cert store */
                break;
        }
    }
    return Py_BuildValue("{sisisi}", "x509", x509, "crl", crl,
        "x509_ca", ca);
}
  

Поскольку SSLContext получает доступ от _SSLContext , SLLContext имеет доступ к методу cert_store_stats .