pitón fuente de interpretación de código bibliotecas de terceros Faker

fuente fondo

Faker es un bibliotecas de terceros Python, proyectos de código abierto GitHub, que se utiliza principalmente para crear los datos ficticios datos creados contienen la clase de información geográfica, información básica como la información personal de cuenta, la creación de redes, información básica como información de tipo de navegador, la información de tipo de archivo, digital texto de clase tipo de cifrado, información de tipo de tiempo, como otras categorías.

Dirección de origen: https://github.com/joke2k/faker
Función rápida recoge: https://blog.csdn.net/qq_41545431/article/details/105006681

fuente de lectura

La interpretación principal fuente

Al hacer clic directamente en la inicialización de clase del módulo de inicialización de clase

fake = Faker(locale='zh_CN')

Manipulación de la código fuente núcleo como sigue:

proxy.py文件
from __future__ import absolute_import, unicode_literals
from collections import OrderedDict
import random
import re
import six
from faker.config import DEFAULT_LOCALE
from faker.factory import Factory
from faker.generator import Generator
from faker.utils.distribution import choices_distribution

class Faker(object):
    """Proxy class capable of supporting multiple locales"""

    cache_pattern = re.compile(r'^_cached_\w*_mapping$')
    generator_attrs = [
        attr for attr in dir(Generator)
        if not attr.startswith('__')
        and attr not in ['seed', 'seed_instance', 'random']
    ]
    def __init__(self, locale=None, providers=None,
                 generator=None, includes=None, **config):
        self._factory_map = OrderedDict()
        self._weights = None

        if isinstance(locale, six.string_types):
            locales = [locale.replace('-', '_')]

        # This guarantees a FIFO ordering of elements in `locales` based on the final
        # locale string while discarding duplicates after processing
        elif isinstance(locale, (list, tuple, set)):
            assert all(isinstance(l, six.string_types) for l in locale)
            locales = []
            for l in locale:
                final_locale = l.replace('-', '_')
                if final_locale not in locales:
                    locales.append(final_locale)

        elif isinstance(locale, OrderedDict):
            assert all(isinstance(v, (int, float)) for v in locale.values())
            odict = OrderedDict()
            for k, v in locale.items():
                key = k.replace('-', '_')
                odict[key] = v
            locales = list(odict.keys())
            self._weights = list(odict.values())

        else:
            locales = [DEFAULT_LOCALE]

        for locale in locales:
            self._factory_map[locale] = Factory.create(locale, providers, generator, includes, **config)

        self._locales = locales
        self.AQ_factories = list(self._factory_map.values())

El archivo de clase principal, y se introdujo en el interior collections.OrderedDict, al azar, otros seis revestimiento exterior.
La siguiente descripción de la tecla correspondiente al estar fuera del paquete:

1, collections.OrderedDict logra diccionario de objetos elementos de clasificación, ya que el diccionario de pitón se almacena de acuerdo con el valor de hash de modo, un trastorno resultante en el diccionario, el OrderedDict diccionario lograr el objeto elementos de ordenación
2, seis nombre proviene de 6 = 2 x 3, que produce principalmente para resolver compatibilidad de código python2 y python3

A partir de inicialización de acuerdo con ciertas reglas de la clase atributos almacenados en los generator_attrs generador, el método para llamadas posteriores. En el inicio especifica la clase en la que los parámetros de inicialización? Al mismo tiempo define nominales dos variables privadas, métodos de clase para evitar las llamadas externas, dijeron que era nominalmente variables privadas en Python es porque no hay una verdadera privatización, independientemente del método o propiedad, con el fin de programar, añade el acuerdo subrayado _ propiedades y métodos no pertenecen a la API, no debe ser visitada fuera de la clase, no serán introducidos desde la importación M *. Nótese, sin embargo al que desea llamar también puede llamar. Se almacena OrderedDict self._factory_map () para una instancia del objeto; self._weights fin de garantizar que la clase se llama, el valor de inicialización de Ninguno dado. El siguiente parámetro es el entorno local de la condición de determinación, un diagrama esquemático que es básicamente como sigue:

proxy.py文件
if isinstance(locale, six.string_types):
    如果入参的locale是字符串,则替换-线为_线,保存在locales中

elif isinstance(locale, (list, tuple, set)):
    如果入参的locale是列表,元祖,集合,则遍历入参判断元素为字符串后将元素替换-线为_线保存在locales中
elif isinstance(locale, OrderedDict):
    如果入参的locale是有序字典,则遍历入参判断键为字符串后将键替换-线为_线保存在locales中,将键的值保存在之前定义的self._weights中
    locales = list(odict.keys())
    self._weights = list(odict.values())
else:
    以上条件都不满足时,将配置文件中自定义的locale保存到列表中赋值给locales

¿Por qué en este local al Senado para hacer tantas cheque, porque la inicialización se realiza la configuración regional una cosa muy importante, pero es muy altas demandas en el punto específico para la localidad de vista Fuente:

proxy.py文件
for locale in locales:
        self._factory_map[locale] = Factory.create(locale, providers, generator, includes, **config)

La fuente principal aquí hizo para crear un mapa para cada diccionario de la lengua, lo que implica el método de creación en el modo de fábrica de la fábrica, los parámetros básicos para la clase actual al Senado. Así Faker Además de la configuración regional en la comprobación de referencia lleva a cabo fuera, no hay ninguna otra verificación hacerlo? La respuesta es sí en el self._weights atributos clave, self._factories, self._factory_map.items (), hecha de sólo lectura cheque, modificada por la decoradora @property externo en el objeto.

Lectura método mágico

Necesidad Ejemplo no hay propiedades de clase instanciada, a continuación, con el fin de aumentar su capacidad de ampliación añadido GetItem método mágico, así que puede falsificar () [ 'pujen'] operación, entonces Faker en falso () [ 'pujen '] volverá a Shane, la operación supone una fuente KeyError, debido Faker supuesto que no se pujen este paquete de idiomas.

proxy.py文件
def __getitem__(self, locale):
    return self._factory_map[locale.replace('-', '_')]
fake = Faker(locale='zh_CN')
print(fake['zh_CN'])

>>>    <faker.generator.Generator object at 0x0000021AEE18FDD8>

Después, mirada en un ejemplo para entender mejor lo que está pasando GetItem método mágico

class Fake(object):
    def __init__(self):
        self.name = 'jack'

    def __getitem__(self,item):
        if item in self.__dict__:       # item = key,判断该key是否存在对象的 __dict__ 里,
            return self.__dict__[item]  # 返回该对象 __dict__ 里key对应的value

    def __setitem__(self, key, value):
        self.__dict__[key] = value      # 在对象 __dict__ 为指定的key设置value

    def __delitem__(self, key):
        del self.__dict__[key]          # 在对象 __dict__ 里删除指定的key

f1 = Fake()
print(f1['name'])   # jack
f1['age'] =10       
print(f1['age'])    # 10
del f1['name']
print(f1.__dict__)  # {'age': 10}

Luego, busquen en el método getattribute__, que aparece en esta clase se debe principalmente a la semilla Prevent () método se llama directamente, sino a la forma Faker.seed () llamadas de ese tipo, la fuente de semillas Faker () en realidad función Generator.seed () es una semilla estocástico. Suponiendo que la clase llamada de método no es semilla (), pero tales otros no-método, a continuación, realiza __getattr método, que es principalmente lo que se hace en Faker en su interior:

proxy.py文件
def __getattr__(self, attr):
    """
    Handles cache access and proxying behavior
    :param attr: attribute name
    :return: the appropriate attribute
    """
    条件语句判断异常情况,最后走如下代码
        factory = self._select_factory(attr)
        return getattr(factory, attr)
patrón de la fábrica

En la inicialización, encontramos que el contenido básico de la final son del patrón de la fábrica Factory.create para crear la próxima vistazo a esta función de fábrica (). Fábrica en el método create () es una clase estática para reflejar

factory.py文件
@classmethod
    def create(
            cls,
            locale=None,
            providers=None,
            generator=None,
            includes=None,
            **config):
        if includes is None:
            includes = []

        # fix locale to package name
        locale = locale.replace('-', '_') if locale else DEFAULT_LOCALE
        locale = pylocale.normalize(locale).split('.')[0]#返回规范化的语言环境代码
        if locale not in AVAILABLE_LOCALES:
            msg = 'Invalid configuration for faker locale `{0}`'.format(locale)
            raise AttributeError(msg)

        config['locale'] = locale
        providers = providers or PROVIDERS#排序的集合

        providers += includes

        faker = generator or Generator(**config)

        for prov_name in providers:
            if prov_name == 'faker.providers':
                continue

            prov_cls, lang_found = cls._get_provider_class(prov_name, locale)#prov_cls=faker.providers,lang_found语言包名称
            provider = prov_cls(faker)#继承在Generator类中
            provider.__provider__ = prov_name
            provider.__lang__ = lang_found
            faker.add_provider(provider)#增加类的方法和属性
        return faker

A partir del código anterior se puede solucionar el problema, el método básico es aumentar y regular la clase sobre el paquete de idioma. Resolvemos algunos de los detalles del interior de código de la misma:

factory.py文件
1、
providers += includes

providers是一个空列表
includes是一个集合数据

那么假设providers=[],includes={1,2,3,4}
则providers += includes运行结果,会使的providers=[1,2,3,4],实际这段代码就是将集合的数据放到空列表中。
2、
faker = generator or Generator(**config)
provider = prov_cls(faker)

这里faker是generator类,prov_cls实际上是一个类,那么prov_cls(faker)实际就是继承了Generator类
3、
provider.__provider__ = prov_name
provider.__lang__ = lang_found
faker.add_provider(provider)#增加类的方法和属性

给这些类赋予方法名和语言包,同时通过魔法方法增加类的方法和属性,这里面涉及到Generator.add_provider()方法
Faker ocultar el principal método en la clase

método anterior el modelo de fábrica create () de la función principal también introdujo sustancialmente sobre otros métodos de clases interna temporal, pero más investigación. A continuación, consulte la fuente () que participan en el método de crear Generator.add_provider (), el método siguiente:

generator.py文件
def  add_provider(self, provider):

    if isinstance(provider, type):
        provider = provider(self)

    self.providers.insert(0, provider)#将provider插入到0索引位置

    for method_name in dir(provider):
        # skip 'private' method
        if method_name.startswith('_'):
            continue

        faker_function = getattr(provider, method_name)#动态运行函数

        if callable(faker_function):#函数用于检查一个对象是否是可调用的
            # add all faker method to generator
            self.set_formatter(method_name, faker_function)

Hacer algunas instrucciones básicas para el uso de los siguientes, seguimos cuando se puede escribir el código como una referencia

if isinstance(provider, type):

Descripción : Si el objeto es una instancia del parámetro ClassInfo parámetros, o es un ejemplo de una subclase (directo, indirecto o virtual), se devuelve True. Si el objeto no es un objeto de un tipo dado, la función siempre devuelve False. Si ClassInfo tupla (o de forma recursiva, las tuplas similares) tipo del objeto, si el objeto es una instancia de cualquier tipo, devuelve True. Si no ClassInfo el tipo o tipos de tuplas, y estos no son el tipo de tuplas de tuplas, el tipo de excepción de error es lanzado.

for method_name in dir(provider):

instrucciones del dir, si el proveedor de clase o módulo no define dir procedimiento vuelve al módulo de proceso de clase o atributo

A continuación, vistazo a estos dos métodos, usado principalmente para llamar dinámicamente la función devuelve un objeto se ejecuta

faker_function = getattr(provider, method_name)#动态运行函数

if callable(faker_function):#函数用于检查一个对象是否是可调用的

Hasta ahora, la clase Generador introduce los métodos básicos para completa!

Faker en cómo ejecutar la lógica interna

Cuando escribimos métodos tienen la intención de echar un vistazo a PyCharm dentro función de clase, Ctrl + clic. cosas extrañas sucedieron, y no entró en ella el método correspondiente a PyCharm simultáneamente nuestros consejos inteligentes:

fake = Faker(locale='zh_CN')
fake.random_digit_not_null()


También puede ser muy claros resultados obtenidos por el análisis de código fuente de arriba, los métodos y las propiedades Faker, ya que siempre se escribe en la misma clase de la siguiente clase, no ver el texto completo de los métodos analíticos básicos y propiedades directamente crear datos ficticios. A continuación, echar un vistazo a la siguiente operación básica de la lógica interna del método de aplicación.

 

Como se muestra, la lógica de funcionamiento interno llama en realidad el método Generator.add_provider bajo contenido generator.py del documento, hay una necesidad de prestar especial atención es la ley, también se mencionó anteriormente, hay un método en el add_provider necesita una atención especial es

for method_name in dir(provider):

Este ciclo básico a través de todos los métodos y propiedades cargadas en el paquete de idioma correspondiente, se dijo propiedades y métodos Faker es en realidad en otro lugar para almacenar el, cuando se utiliza en la toma de control, el Faker de hacerlo propia clase parece simple. Entonces, ¿qué forma externa para almacenarlo?


Puede ser visto fuera de un paquete de proveedor, el paquete que corresponde a un número de método de clasificación de paquetes, el método es para bajar el nivel interno correspondiente a cada paquete de idioma. Mira la representación interna del método de la forma específica de

 


Básica se puede encontrar en base a los datos brutos almacenados en la forma ancestral, terminamos resultado es la manera de funcionar de esta, entonces el método de la función y, finalmente, cómo ejecutarlo? De hecho, la parte superior del código fuente para analizar ya se ha mencionado, es el uso de la init () en

 

return getattr(factory, attr)

Específicos para cada aplicación del método o función debido al exceso no recita una amplia gama de esto es el uso de la biblioteca básica aleatoria de lograr.

Artículo original apareció por primera vez en el número de micro-canal público de la clase micro pruebas de software

Supongo que te gusta

Origin www.cnblogs.com/pujenyuan/p/12615835.html
Recomendado
Clasificación