我试图理解这篇(主要是非常有用的)文章,它描述了如何使用 react 的上下文 API 来管理应用程序级状态。对于一个简单的应用程序(在这种情况下是一个基本的计数器应用程序),它使用以下解决方案:
const CountContext = React.createContext()
function CountProvider(props) {
const [count, setCount] = React.useState(0)
const value = React.useMemo(() => [count, setCount], [count])
return <CountContext.Provider value={value} {...props} />
}
Run Code Online (Sandbox Code Playgroud)
提供上下文,然后提供以下钩子,它可以在组件树下某处的组件中使用:
function useCount() {
const context = React.useContext(CountContext)
if (!context) {
throw new Error(`useCount must be used within a CountProvider`)
}
return context
}
Run Code Online (Sandbox Code Playgroud)
我正在努力理解为什么useMemo这里需要钩子。这里没有涉及特别繁重的计算,所以我不确定我们为什么要记住这些值。如果上下文提供程序如下所示,这是否也能正常工作:
function CountProvider(props) {
const [count, setCount] = React.useState(0)
return <CountContext.Provider value={value} {...props} />
}
Run Code Online (Sandbox Code Playgroud)
我觉得可能有什么我错过了!!
我正在尝试创建一个生成器,它返回给定范围内的数字,该数字通过函数给出的特定测试foo.但是我希望这些数字以随机顺序进行测试.以下代码将实现此目的:
from random import shuffle
def MyGenerator(foo, num):
order = list(range(num))
shuffle(order)
for i in order:
if foo(i):
yield i
Run Code Online (Sandbox Code Playgroud)
问题
该解决方案的问题在于,有时范围将非常大(num可能是有序的10**8和向上的).在内存中有这么大的列表时,这个功能会变慢.我试图通过以下代码避免此问题:
from random import randint
def MyGenerator(foo, num):
tried = set()
while len(tried) <= num - 1:
i = randint(0, num-1)
if i in tried:
continue
tried.add(i)
if foo(i):
yield i
Run Code Online (Sandbox Code Playgroud)
这在大多数情况下运行良好,因为在大多数情况下num会非常大,foo会传递合理数量的数字,并且__next__调用该方法的总次数会相对较少(例如,最多200次通常要小得多) .因此,我们可能会偶然发现通过foo测试的值,并且tried永远不会变大.(即使它只通过10%的时间,我们也不会期望tried大致超过2000左右.)
但是,当它num很小时(接近__next__调用该方法的次数,或者foo大部分时间都失败),上述解决方案变得非常低效 - …
jest提供afterEach,beforeEach,afterAll和beforeAll要完成安装和拆卸的逻辑。我想做的是在一次特定测试后清理。考虑以下:
describe("a family of tests it makes sense to group together", () => {
...
test("something I want to test", () => {
// some setup needed for just this test
global.foo = "bar"
// the test
expect(myTest()).toBe(true)
// clear up
delete global.foo
}
...
}
Run Code Online (Sandbox Code Playgroud)
如果上述测试由于某种原因失败,则delete global.foo永远不会运行。这意味着它之后的所有测试可能都会失败。我没有看到 1 个测试失败,而是看到大量测试失败,这可能会令人困惑。
一种解决方案是添加delete global.foo到我的afterEach. 不需要在每次测试后都运行它,但它也没有任何危害。另一种解决方案是单独放置特定的测试,以便afterEach仅适用于它。但这似乎也不理想 - 如果该测试属于其他测试,那么它就不可能与它们一起存在。
有没有办法只为特定测试运行拆卸逻辑(而不在实际测试中运行它)。在我的特定用例中,第一个概述的解决方案很好,但我可以想象可能存在需要更细粒度控制的情况。例如,如果我的拆卸方法需要很长时间,我就不想重复很多次,因为这会减慢整个测试套件的速度。
我希望这不是重复,如果是这样,我道歉,但已经做了一些谷歌搜索,并查看堆栈溢出,还没有找到任何东西...
MCVE
我理解,如果一个函数不断调用自身,这不会无限期地发生而没有堆栈溢出,因此在一定限制之后会引发错误.例如:
def foo():
return foo()
foo()
Run Code Online (Sandbox Code Playgroud)
这会导致以下错误:
RecursionError: maximum recursion depth exceeded
Run Code Online (Sandbox Code Playgroud)
但是,如果我编写如下函数:
def count(n):
if n == 0:
return 0
else:
return count(n-1)+1
count(1000)
Run Code Online (Sandbox Code Playgroud)
我得到一个稍微不同的错误:
RecursionError: maximum recursion depth exceeded in comparison
Run Code Online (Sandbox Code Playgroud)
这个问题
在上述错误中引用的"比较"是什么.我想我要问的是这两种情况之间有什么区别,这会导致两种不同的错误.
我有一个通常接受列表的函数,但有时也需要接受函数。有几种方法可以解决这个问题,但是能够len(foo)为给定的函数做这件事会非常有用foo。
最后,我没有传入函数,而是传入了__len__定义了函数的可调用类。但这让我开始思考,因为在 python 中一切都是对象,函数可以具有属性等,只是出于好奇......
题
有没有办法给一个函数一个len?一个快速的谷歌没有提出任何东西。
我的尝试
def foo():
return True
def my_len(self):
return 5
foo.__len__ = my_len
len(foo)
Run Code Online (Sandbox Code Playgroud) 这是我的settings.py:
INSTALLED_APPS = [
'rest_framework',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'api.apps.ApiConfig'
]
Run Code Online (Sandbox Code Playgroud) python ×4
reactjs ×2
django ×1
function ×1
generator ×1
javascript ×1
jestjs ×1
performance ×1
python-3.x ×1
react-hooks ×1
recursion ×1
rest ×1
shuffle ×1
state ×1
teardown ×1
testing ×1