Importaciones relativas por mil millonésima vez

815
Noname 2013-01-03 17:50.

Yo he estado aquí:

  • http://www.python.org/dev/peps/pep-0328/
  • http://docs.python.org/2/tutorial/modules.html#packages
  • Paquetes de Python: importaciones relativas
  • El código de ejemplo de importación relativa de Python no funciona
  • Importaciones relativas en Python 2.5
  • Importaciones relativas en Python
  • Python: deshabilitar la importación relativa

y muchas URL que no copié, algunas en SO, otras en otros sitios, cuando pensé que tendría la solución rápidamente.

La pregunta que siempre se repite es la siguiente: con Windows 7, Python 2.7.3 de 32 bits, ¿cómo resuelvo este mensaje de "Intento de importación relativa en un no paquete"? Construí una réplica exacta del paquete en pep-0328:

package/
    __init__.py
    subpackage1/
        __init__.py
        moduleX.py
        moduleY.py
    subpackage2/
        __init__.py
        moduleZ.py
    moduleA.py

Las importaciones se realizaron desde la consola.

Hice funciones llamadas spam y huevos en sus módulos apropiados. Naturalmente, no funcionó. Aparentemente, la respuesta está en la cuarta URL que enumeré, pero para mí son todos antiguos alumnos. Hubo esta respuesta en una de las URL que visité:

Las importaciones relativas utilizan el atributo de nombre de un módulo para determinar la posición de ese módulo en la jerarquía de paquetes. Si el nombre del módulo no contiene información de paquete (por ejemplo, está configurado como 'principal'), las importaciones relativas se resuelven como si el módulo fuera un módulo de nivel superior, independientemente de dónde se encuentre realmente el módulo en el sistema de archivos.

La respuesta anterior parece prometedora, pero para mí son todos jeroglíficos. Entonces, mi pregunta, ¿cómo puedo hacer que Python no me regrese "Intento de importación relativa en un paquete no"? tiene una respuesta que involucra -m, supuestamente.

¿Alguien puede decirme por qué Python da ese mensaje de error, qué significa "sin paquete", por qué y cómo se define un "paquete", y la respuesta precisa expresada en términos lo suficientemente fáciles de entender para un niño de kindergarten ?

10 answers

1163
BrenBarn 2013-01-03 18:06.

Secuencia de comandos frente a módulo

Aquí tienes una explicación. La versión corta es que hay una gran diferencia entre ejecutar directamente un archivo Python e importar ese archivo desde otro lugar. El simple hecho de saber en qué directorio se encuentra un archivo no determina en qué paquete Python cree que está. Eso depende, además, de cómo se carga el archivo en Python (ejecutándolo o importándolo).

Hay dos formas de cargar un archivo Python: como script de nivel superior o como módulo. Un archivo se carga como script de nivel superior si lo ejecuta directamente, por ejemplo, escribiendo python myfile.pyen la línea de comando. Se carga como un módulo si lo hace python -m myfile, o si se carga cuando importse encuentra una declaración dentro de algún otro archivo. Solo puede haber una secuencia de comandos de nivel superior a la vez; la secuencia de comandos de nivel superior es el archivo Python que ejecutó para comenzar.

Nombrar

Cuando se carga un archivo, se le asigna un nombre (que se almacena en su __name__atributo). Si se cargó como script de nivel superior, su nombre es __main__. Si se cargó como un módulo, su nombre es el nombre del archivo, precedido por los nombres de los paquetes / subpaquetes de los que forma parte, separados por puntos.

Entonces, por ejemplo, en su ejemplo:

package/
    __init__.py
    subpackage1/
        __init__.py
        moduleX.py
    moduleA.py

si lo importó moduleX(nota: importado , no ejecutado directamente), su nombre sería package.subpackage1.moduleX. Si lo importara moduleA, su nombre sería package.moduleA. Sin embargo, si ejecuta directamente moduleX desde la línea de comando, su nombre será __main__, y si lo ejecuta directamente moduleAdesde la línea de comando, su nombre será __main__. Cuando un módulo se ejecuta como script de nivel superior, pierde su nombre normal y su nombre es __main__.

Accediendo a un módulo NO a través de su paquete contenedor

Hay una arruga adicional: el nombre del módulo depende de si se importó "directamente" del directorio en el que se encuentra o se importó a través de un paquete. Esto solo hace una diferencia si ejecuta Python en un directorio e intenta importar un archivo en ese mismo directorio (o un subdirectorio del mismo). Por ejemplo, si inicia el intérprete de Python en el directorio package/subpackage1y luego lo hace import moduleX, el nombre de moduleXserá moduleX, y no package.subpackage1.moduleX. Esto se debe a que Python agrega el directorio actual a su ruta de búsqueda al inicio; si encuentra el módulo que se va a importar en el directorio actual, no sabrá que ese directorio es parte de un paquete y la información del paquete no pasará a formar parte del nombre del módulo.

Un caso especial es si ejecuta el intérprete de manera interactiva (por ejemplo, simplemente escriba pythony comience a ingresar el código Python sobre la marcha). En este caso, el nombre de esa sesión interactiva es __main__.

Ahora, aquí está lo crucial para su mensaje de error: si el nombre de un módulo no tiene puntos, no se considera parte de un paquete . No importa dónde se encuentre realmente el archivo en el disco. Todo lo que importa es cuál es su nombre, y su nombre depende de cómo lo cargó.

Ahora mire la cita que incluyó en su pregunta:

Las importaciones relativas utilizan el atributo de nombre de un módulo para determinar la posición de ese módulo en la jerarquía de paquetes. Si el nombre del módulo no contiene información de paquete (por ejemplo, está configurado como 'principal'), las importaciones relativas se resuelven como si el módulo fuera un módulo de nivel superior, independientemente de dónde se encuentre realmente el módulo en el sistema de archivos.

Importaciones relativas ...

Las importaciones relativas utilizan el nombre del módulo para determinar dónde se encuentra en un paquete. Cuando usa una importación relativa como from .. import foo, los puntos indican que debe aumentar un cierto número de niveles en la jerarquía del paquete. Por ejemplo, si el nombre de su módulo actual es package.subpackage1.moduleX, ..moduleAsignificaría package.moduleA. Para from .. importque funcione, el nombre del módulo debe tener al menos tantos puntos como hay en la importdeclaración.

... son solo relativos en un paquete

Sin embargo, si el nombre de su módulo es __main__, no se considera que esté en un paquete. Su nombre no tiene puntos y, por lo tanto, no puede usar from .. importdeclaraciones dentro de él. Si intenta hacerlo, obtendrá el error "importación relativa en no paquete".

Los scripts no se pueden importar relativos

Lo que probablemente hizo fue intentar ejecutar moduleXo similar desde la línea de comandos. Cuando hizo esto, su nombre se estableció en __main__, lo que significa que las importaciones relativas dentro de él fallarán, porque su nombre no revela que está en un paquete. Tenga en cuenta que esto también sucederá si ejecuta Python desde el mismo directorio donde está un módulo, y luego intenta importar ese módulo, porque, como se describió anteriormente, Python encontrará el módulo en el directorio actual "demasiado pronto" sin darse cuenta de que es parte de un paquete.

Recuerde también que cuando ejecuta el intérprete interactivo, el "nombre" de esa sesión interactiva es siempre __main__. Por lo tanto, no puede realizar importaciones relativas directamente desde una sesión interactiva . Las importaciones relativas solo se utilizan en archivos de módulo.

Dos soluciones:

  1. Si realmente desea ejecutarlo moduleXdirectamente, pero aún desea que se considere parte de un paquete, puede hacerlo python -m package.subpackage1.moduleX. Le -mdice a Python que lo cargue como un módulo, no como la secuencia de comandos de nivel superior.

  2. O quizás no quiera ejecutarlo moduleX , solo quiere ejecutar algún otro script, digamos myfile.py, que use funciones internas moduleX. Si ese es el caso, colóquelo myfile.py en otro lugar , no dentro del packagedirectorio, y ejecútelo. Si por dentro myfile.pyhaces cosas como estas from package.moduleA import spam, funcionará bien.

Notas

  • Para cualquiera de estas soluciones, el directorio del paquete ( packageen su ejemplo) debe ser accesible desde la ruta de búsqueda del módulo Python ( sys.path). Si no es así, no podrá utilizar nada del paquete de forma fiable.

  • Desde Python 2.6, el "nombre" del módulo para propósitos de resolución de paquetes está determinado no solo por sus __name__atributos sino también por el __package__atributo. Por eso evito usar el símbolo explícito __name__para referirme al "nombre" del módulo. Desde Python 2.6, el "nombre" de un módulo es efectivamente __package__ + '.' + __name__, o solo __name__si lo __package__es None).

50
Rami Ka. 2018-03-26 09:50.

Este es realmente un problema dentro de Python. El origen de la confusión es que la gente toma erróneamente la importancia relativa como un camino relativo que no lo es.

Por ejemplo, cuando escribe en faa.py :

from .. import foo

Esto tiene significado solo si faa.py fue identificado y cargado por python, durante la ejecución, como parte de un paquete. En ese caso, el nombre del módulo para faa.py sería, por ejemplo, some_packagename.faa . Si el archivo se cargó solo porque está en el directorio actual, cuando se ejecuta Python, entonces su nombre no se referirá a ningún paquete y, finalmente, la importación relativa fallará.

Una solución simple para referir módulos en el directorio actual es usar esto:

if __package__ is None or __package__ == '':
    # uses current directory visibility
    import foo
else:
    # uses current package visibility
    from . import foo
9
torek 2017-05-06 16:08.

Aquí hay una receta general, modificada para que encaje como un ejemplo, que estoy usando ahora mismo para tratar con bibliotecas de Python escritas como paquetes, que contienen archivos interdependientes, donde quiero poder probar partes de ellos por partes. Llamemos a esto lib.fooy digamos que necesita acceso a lib.fileApara funciones f1y f2, y lib.fileBpara clase Class3.

He incluido algunas printllamadas para ayudar a ilustrar cómo funciona esto. En la práctica, querrá eliminarlos (y tal vez también la from __future__ import print_functionlínea).

Este ejemplo en particular es demasiado simple para mostrar cuándo realmente necesitamos insertar una entrada en sys.path. (Vea la respuesta de Lars para un caso en el que lo necesitamos, cuando tenemos dos o más niveles de directorios de paquetes, y luego usamos, os.path.dirname(os.path.dirname(__file__))pero tampoco duele mucho aquí). También es lo suficientemente seguro para hacer esto sin el if _i in sys.pathprueba. Sin embargo, si cada archivo importado se inserta el mismo camino; por ejemplo, si ambos fileAy fileBquieren utilidades de importación de los paquetes-este estorba hasta sys.pathcon el mismo camino muchas veces, por lo que es bueno tener el if _i not in sys.pathen el texto modelo.

from __future__ import print_function # only when showing how this works

if __package__:
    print('Package named {!r}; __name__ is {!r}'.format(__package__, __name__))
    from .fileA import f1, f2
    from .fileB import Class3
else:
    print('Not a package; __name__ is {!r}'.format(__name__))
    # these next steps should be used only with care and if needed
    # (remove the sys.path manipulation for simple cases!)
    import os, sys
    _i = os.path.dirname(os.path.abspath(__file__))
    if _i not in sys.path:
        print('inserting {!r} into sys.path'.format(_i))
        sys.path.insert(0, _i)
    else:
        print('{!r} is already in sys.path'.format(_i))
    del _i # clean up global name space

    from fileA import f1, f2
    from fileB import Class3

... all the code as usual ...

if __name__ == '__main__':
    import doctest, sys
    ret = doctest.testmod()
    sys.exit(0 if ret.failed == 0 else 1)

La idea aquí es la siguiente (y tenga en cuenta que todos funcionan de la misma manera en python2.7 y python 3.x):

  1. Si se ejecuta como import libo from lib import foocomo una importación de paquete regular desde código ordinario, __packagees liby __name__es lib.foo. Tomamos la primera ruta de código, importando desde .fileA, etc.

  2. Si se ejecuta como python lib/foo.py, __package__será Ninguno y __name__lo será __main__.

    Tomamos la segunda ruta de código. El libdirectorio ya estará en, sys.pathpor lo que no es necesario agregarlo. Importamos desde fileA, etc.

  3. Si se ejecuta dentro del libdirectorio como python foo.py, el comportamiento es el mismo que para el caso 2.

  4. Si se ejecuta dentro del libdirectorio como python -m foo, el comportamiento es similar a los casos 2 y 3. Sin embargo, la ruta al libdirectorio no está sys.path, por lo que la agregamos antes de importar. Lo mismo se aplica si ejecutamos Python y luego import foo.

    (Dado que . está en sys.path, realmente no necesitamos agregar la versión absoluta de la ruta aquí. Aquí es donde una estructura de anidación de paquetes más profunda, donde queremos hacerlo from ..otherlib.fileC import ..., marca la diferencia. Si no está haciendo esto, puede omitir toda la sys.pathmanipulación por completo.)

Notas

Todavía hay una peculiaridad. Si ejecuta todo esto desde afuera:

$ python2 lib.foo

o:

$ python3 lib.foo

el comportamiento depende del contenido de lib/__init__.py. Si eso existe y está vacío , todo está bien:

Package named 'lib'; __name__ is '__main__'

Pero si lib/__init__.py se importa routinepara poder exportar routine.namedirectamente como lib.name, obtiene:

$ python2 lib.foo
Package named 'lib'; __name__ is 'lib.foo'
Package named 'lib'; __name__ is '__main__'

Es decir, el módulo se importa dos veces, una a través del paquete y luego otra vez __main__para que ejecute su maincódigo. Python 3.6 y versiones posteriores advierten sobre esto:

$ python3 lib.routine
Package named 'lib'; __name__ is 'lib.foo'
[...]/runpy.py:125: RuntimeWarning: 'lib.foo' found in sys.modules
after import of package 'lib', but prior to execution of 'lib.foo';
this may result in unpredictable behaviour
  warn(RuntimeWarning(msg))
Package named 'lib'; __name__ is '__main__'

La advertencia es nueva, pero el comportamiento advertido no lo es. Es parte de lo que algunos llaman la trampa de la doble importación . (Para obtener más detalles, consulte el número 27487 ). Nick Coghlan dice:

Esta siguiente trampa existe en todas las versiones actuales de Python, incluida la 3.3, y se puede resumir en la siguiente pauta general: "Nunca agregue un directorio de paquete, o cualquier directorio dentro de un paquete, directamente a la ruta de Python".

Tenga en cuenta que si bien violamos esa regla aquí, lo hacemos solo cuando el archivo que se está cargando no se está cargando como parte de un paquete, y nuestra modificación está diseñada específicamente para permitirnos acceder a otros archivos en ese paquete. (Y, como señalé, probablemente no deberíamos hacer esto en absoluto para paquetes de un solo nivel). Si quisiéramos ser más limpios, podríamos reescribir esto como, por ejemplo:

    import os, sys
    _i = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    if _i not in sys.path:
        sys.path.insert(0, _i)
    else:
        _i = None

    from sub.fileA import f1, f2
    from sub.fileB import Class3

    if _i:
        sys.path.remove(_i)
    del _i

Es decir, modificamos el sys.pathtiempo suficiente para lograr nuestras importaciones, luego lo volvemos a colocar como estaba (eliminando una copia de _isi y solo si agregamos una copia de _i).

8
Steve L 2018-10-05 15:08.

Entonces, después de quejarme sobre esto junto con muchos otros, me encontré con una nota publicada por Dorian B en este artículo que resolvió el problema específico que tenía donde desarrollaría módulos y clases para usar con un servicio web, pero también quiero estar capaz de probarlos mientras estoy codificando, usando las instalaciones de depuración en PyCharm. Para ejecutar pruebas en una clase autónoma, incluiría lo siguiente al final de mi archivo de clase:

if __name__ == '__main__':
   # run test code here...

pero si quisiera importar otras clases o módulos en la misma carpeta, tendría que cambiar todas mis declaraciones de importación de notación relativa a referencias locales (es decir, eliminar el punto (.)) Pero después de leer la sugerencia de Dorian, probé su ' one-liner 'y funcionó! ¡Ahora puedo probar en PyCharm y dejar mi código de prueba en su lugar cuando uso la clase en otra clase bajo prueba, o cuando la uso en mi servicio web!

# import any site-lib modules first, then...
import sys
parent_module = sys.modules['.'.join(__name__.split('.')[:-1]) or '__main__']
if __name__ == '__main__' or parent_module.__name__ == '__main__':
    from codex import Codex # these are in same folder as module under test!
    from dblogger import DbLogger
else:
    from .codex import Codex
    from .dblogger import DbLogger

La instrucción if comprueba si estamos ejecutando este módulo como principal o si se está utilizando en otro módulo que se está probando como principal . Quizás esto sea obvio, pero ofrezco esta nota aquí en caso de que alguien más frustrado por los problemas de importación relativos anteriores pueda hacer uso de ella.

5
Federico 2016-06-21 16:06.

Aquí hay una solución que no recomendaría, pero que podría ser útil en algunas situaciones en las que los módulos simplemente no se generaron:

import os
import sys
parent_dir_name = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(parent_dir_name + "/your_dir")
import your_script
your_script.a_function()
2
Lars 2016-07-20 00:28.

Tuve un problema similar en el que no quería cambiar la ruta de búsqueda del módulo Python y necesitaba cargar un módulo relativamente desde un script (a pesar de que "los scripts no se pueden importar en relación con todos", como BrenBarn explicó muy bien arriba).

Entonces utilicé el siguiente truco. Desafortunadamente, se basa en el impmódulo que quedó obsoleto desde la versión 3.4 para ser eliminado importlib. (¿Esto también es posible con importlib? No lo sé). Aún así, el truco funciona por ahora.

Ejemplo para acceder a miembros de moduleXin subpackage1desde un script que reside en la subpackage2carpeta:

#!/usr/bin/env python3

import inspect
import imp
import os

def get_script_dir(follow_symlinks=True):
    """
    Return directory of code defining this very function.
    Should work from a module as well as from a script.
    """
    script_path = inspect.getabsfile(get_script_dir)
    if follow_symlinks:
        script_path = os.path.realpath(script_path)
    return os.path.dirname(script_path)

# loading the module (hack, relying on deprecated imp-module)
PARENT_PATH = os.path.dirname(get_script_dir())
(x_file, x_path, x_desc) = imp.find_module('moduleX', [PARENT_PATH+'/'+'subpackage1'])
module_x = imp.load_module('subpackage1.moduleX', x_file, x_path, x_desc)

# importing a function and a value
function = module_x.my_function
VALUE = module_x.MY_CONST

Un enfoque más limpio parece ser modificar el sys.path utilizado para cargar módulos como lo menciona Federico.

#!/usr/bin/env python3

if __name__ == '__main__' and __package__ is None:
    from os import sys, path
    # __file__ should be defined in this case
    PARENT_DIR = path.dirname(path.dirname(path.abspath(__file__)))
   sys.path.append(PARENT_DIR)
from subpackage1.moduleX import *
2
theodox 2013-01-03 18:01.

__name__ cambia dependiendo de si el código en cuestión se ejecuta en el espacio de nombres global o como parte de un módulo importado.

Si el código no se está ejecutando en el espacio global, __name__será el nombre del módulo. Si se está ejecutando en un espacio de nombres global, por ejemplo, si lo escribe en una consola, o ejecuta el módulo como un script usando python.exe yourscriptnamehere.pyentonces se __name__convierte "__main__".

Verá que if __name__ == '__main__'se usa una gran cantidad de código Python para probar si el código se está ejecutando desde el espacio de nombres global, lo que le permite tener un módulo que también funciona como un script.

¿Intentaste hacer estas importaciones desde la consola?

2
Brad Dre 2019-08-09 13:18.

La respuesta de @ BrenBarn lo dice todo, pero si eres como yo, puede que te lleve un tiempo entenderlo. Este es mi caso y cómo se aplica la respuesta de @ BrenBarn, tal vez te ayude.

El caso

package/
    __init__.py
    subpackage1/
        __init__.py
        moduleX.py
    moduleA.py

Usando nuestro ejemplo familiar, y agregue que moduleX.py tiene una importación relativa a ..moduleA. Dado que intenté escribir un script de prueba en el directorio subpackage1 que importó moduleX, pero luego obtuve el temido error descrito por el OP.

Solución

Mueva el script de prueba al mismo nivel que el paquete e importe package.subpackage1.moduleX

Explicación

Como se explicó, las importaciones relativas se realizan en relación con el nombre actual. Cuando mi script de prueba importa moduleX desde el mismo directorio, entonces el nombre del módulo dentro de moduleX es moduleX. Cuando encuentra una importación relativa, el intérprete no puede realizar una copia de seguridad de la jerarquía del paquete porque ya está en la parte superior.

Cuando importo moduleX desde arriba, el nombre dentro de moduleX es package.subpackage1.moduleX y se puede encontrar la importación relativa

1
ec2604 2018-02-25 06:11.

Las importaciones relativas utilizan el atributo de nombre de un módulo para determinar la posición de ese módulo en la jerarquía de paquetes. Si el nombre del módulo no contiene información de paquete (por ejemplo, está configurado como 'principal'), las importaciones relativas se resuelven como si el módulo fuera un módulo de nivel superior, independientemente de dónde se encuentre realmente el módulo en el sistema de archivos.

Escribí un pequeño paquete de Python para PyPi que podría ayudar a los espectadores a responder esta pregunta. El paquete actúa como una solución si uno desea poder ejecutar archivos de Python que contienen importaciones que contienen paquetes de nivel superior desde dentro de un paquete / proyecto sin estar directamente en el directorio del archivo de importación.https://pypi.org/project/import-anywhere/

0
Smit Johnth 2020-11-21 14:32.

Otra solución sucia pero funcional. Asume que estás en el nivel superior de tu paquete.

import sys
from os.path import dirname, basename

if __package__ is None:
    sys.path.append('..')
    __package__ = basename(dirname(sys.argv[0]))

from . import your_module

La ventaja frente a otra respuesta aquí es que no es necesario cambiar las importaciones que IDE genera automáticamente.

Related questions

MORE COOL STUFF

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que le diagnosticaron envenenamiento por mercurio y plomo, probablemente debido a su trabajo como manipuladora de casas.

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

Recientemente salió a la luz un informe policial que acusa a la estrella de 'Love Is Blind', Brennon, de violencia doméstica. Ahora, Brennon ha respondido a los reclamos.

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Conozca cómo Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia mientras organizaba la primera celebración de Acción de Gracias desde que murió su madre, Naomi Judd.

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Descubra por qué un destacado experto en lenguaje corporal cree que es fácil trazar "tales paralelismos" entre la princesa Kate Middleton y la princesa Diana.

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los inodoros arrojan columnas de aerosol invisibles con cada descarga. ¿Como sabemos? La prueba fue capturada por láseres de alta potencia.

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

¿Caduca el repelente de insectos?

¿Caduca el repelente de insectos?

¿Sigue siendo efectivo ese lote de repelente de insectos que te quedó del verano pasado? Si es así, ¿por cuánto tiempo?

Estados Unidos podría evitarse el horror del nuevo gran horneado británico

Estados Unidos podría evitarse el horror del nuevo gran horneado británico

Si este tráiler de pesadilla de la temporada más reciente de Great British Bake Off te asustó y te hizo no volver a ver el programa, es posible que tengas suerte: PBS no ha decidido si se transmitirá o no la última temporada en los Estados Unidos. actualización, para aquellos que no siguen sin aliento este tipo de drama de nicho: el presentador Paul Hollywood y la hermosa carpa llena de batidoras de colores pastel y cuadros se trasladaron de la BBC al Canal 4; Mary Berry, Sue Perkins y Mel Giedroyc renunciaron.

Atún como Oh, Hello llega a Netflix

Atún como Oh, Hello llega a Netflix

Foto: Netflix Oh, Hello On Broadway (Netflix): Después de llegar a Broadway el año pasado, los dos locos del Upper West Side interpretados por John Mulaney y Nick Kroll finalmente llegaron a Netflix. El especial consta del espectáculo en el escenario, algunos momentos entre bastidores y un invitado muy especial de “Too Much Tuna”.

Actualice a un Sonicare por tan solo $ 30

Actualice a un Sonicare por tan solo $ 30

¿Quiere probar un cepillo de dientes Sonicare sin gastar mucho dinero en uno de sus modelos favoritos de gama alta? Puede comprar un kit de la Serie 2 o Serie 3 por tan solo $ 30 hoy en Amazon. Haga clic aquí para ver la lista completa de modelos elegibles y tenga en cuenta que se descontarán $ 10 adicionales en su carrito.

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Tapas elásticas de silicona de Tomorrow's Kitchen, paquete de 12 | $14 | Amazonas | Código promocional 20OFFKINJALids son básicamente los calcetines de la cocina; siempre perdiéndose, dejando contenedores huérfanos que nunca podrán volver a cerrarse. Pero, ¿y si sus tapas pudieran estirarse y adaptarse a todos los recipientes, ollas, sartenes e incluso frutas en rodajas grandes que sobran? Nunca más tendrás que preocuparte por perder esa tapa tan específica.

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

El equipo está a la espera de las medallas que ganó en los Juegos Olímpicos de Invierno de 2022 en Beijing, ya que se está resolviendo un caso de dopaje que involucra a la patinadora artística rusa Kamila Valieva.

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Miles de compradores de Amazon recomiendan la funda de almohada de seda Mulberry, y está a la venta en este momento. La funda de almohada de seda viene en varios colores y ayuda a mantener el cabello suave y la piel clara. Compre las fundas de almohada de seda mientras tienen hasta un 46 por ciento de descuento en Amazon

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

El jueves se presentó una denuncia de delito menor amenazante agravado contra Joe Mixon.

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

El Departamento de Policía de Lafayette comenzó a investigar a un profesor de la Universidad de Purdue en diciembre después de recibir varias denuncias de un "hombre sospechoso que se acercaba a una mujer".

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Al igual que el mundo que nos rodea, el lenguaje siempre está cambiando. Mientras que en eras anteriores los cambios en el idioma ocurrían durante años o incluso décadas, ahora pueden ocurrir en cuestión de días o incluso horas.

India me está pateando el culo

India me está pateando el culo

Estoy de vuelta por primera vez en seis años. No puedo decirte cuánto tiempo he estado esperando esto.

ℝ

“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.

¿Merrick Garland le ha fallado a Estados Unidos?

Es más de la mitad de la presidencia de Biden. ¿Qué está esperando Merrick Garland?

¿Merrick Garland le ha fallado a Estados Unidos?

Creo, un poco tarde en la vida, en dar oportunidades a la gente. Generosamente.

Language