相关疑难解决方法(0)

为什么"可变的默认参数修复"语法如此丑陋,请问python newbie

现在跟随我的一系列"python新手问题"并基于另一个问题.

特权

转到http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables并向下滚动到"默认参数值".在那里你可以找到以下内容:

def bad_append(new_item, a_list=[]):
    a_list.append(new_item)
    return a_list

def good_append(new_item, a_list=None):
    if a_list is None:
        a_list = []
    a_list.append(new_item)
    return a_list
Run Code Online (Sandbox Code Playgroud)

在python.org上甚至还有一个"重要的警告",这个例子非常相同,并不是说它"更好".

一种方式来表达它

所以,这里的问题是:为什么在一个已知问题上"好"语法比在一个促进"优雅语法"和"易于使用"的编程语言中那样丑陋?

编辑:

另一种说法

我不是在问为什么或如何发生(感谢Mark的链接).

我问为什么没有更简单的替代内置语言.

我认为更好的方法可能是在def自身中做一些事情,其中name参数将附加到def可变对象中的"本地"或"新" .就像是:

def better_append(new_item, a_list=immutable([])):
    a_list.append(new_item)
    return a_list
Run Code Online (Sandbox Code Playgroud)

我相信有人可以提供更好的语法,但我也猜测必须有一个非常好的解释为什么没有这样做.

python mutable names

28
推荐指数
3
解决办法
2303
查看次数

Redis vs Disk在缓存应用程序中的性能

我想在python中创建一个redis缓存,就像任何一个自尊的科学家一样,我做了一个基准测试来测试性能.

有趣的是,redis并没有那么好.要么Python正在做一些神奇的事情(存储文件),要么我的版本的redis非常慢.

我不知道这是因为我的代码的结构方式,还是什么,但是我期待redis比它更好.

要创建redis缓存,我将二进制数据(在本例中为HTML页面)设置为从文件名派生的密钥,其有效期为5分钟.

在所有情况下,使用f.read()完成文件处理(这比f.readlines()快约3倍,我需要二进制blob).

在我的比较中是否存在我缺少的东西,或者Redis真的与磁盘不匹配?Python是否在某处缓存文件,并且每次都重新访问它?为什么这比访问redis要快得多?

我在64位Ubuntu系统上使用redis 2.8,python 2.7和redis-py.

我不认为Python正在做任何特别神奇的事情,因为我创建了一个将文件数据存储在python对象中并永久产生它的函数.

我有四个函数调用我分组:

读取文件X次

调用一个函数来查看redis对象是否仍在内存中,加载它或缓存新文件(单个和多个redis实例).

一个创建生成器的函数,该生成器从redis数据库生成结果(具有redis的单个和多个实例).

最后,将文件存储在内存中并永久生成.

import redis
import time

def load_file(fp, fpKey, r, expiry):
    with open(fp, "rb") as f:
        data = f.read()
    p = r.pipeline()
    p.set(fpKey, data)
    p.expire(fpKey, expiry)
    p.execute()
    return data

def cache_or_get_gen(fp, expiry=300, r=redis.Redis(db=5)):
    fpKey = "cached:"+fp

    while True:
        yield load_file(fp, fpKey, r, expiry)
        t = time.time()
        while time.time() - t - expiry < 0:
            yield r.get(fpKey)


def cache_or_get(fp, expiry=300, r=redis.Redis(db=5)):

    fpKey = "cached:"+fp

    if r.exists(fpKey):
        return r.get(fpKey) …
Run Code Online (Sandbox Code Playgroud)

python performance caching generator redis

28
推荐指数
1
解决办法
1万
查看次数

tkinter在for循环传递命令参数中创建按钮

我试图在for循环中创建tkinter中的按钮.并且每个循环都将i count值作为参数传递给命令值.因此,当从命令值调用函数时,我可以判断按下了哪个按钮并相应地执行操作.问题是,假设len为3,它将创建3个按钮,标题为"Game 1"到"Game 3",但是当按下任何按钮时,打印值总是2,即最后一次迭代.因此看起来按钮是作为单独的实体制作的,但命令参数中的i值似乎完全相同.这是代码:

def createGameURLs(self):
    self.button = []
    for i in range(3):
        self.button.append(Button(self, text='Game '+str(i+1),command=lambda:self.open_this(i)))
        self.button[i].grid(column=4, row=i+1, sticky=W)
def open_this(self, myNum):
    print(myNum)
Run Code Online (Sandbox Code Playgroud)

有没有办法在每次迭代时获得当前的i值以坚持使用该特定按钮?

python tkinter button

26
推荐指数
2
解决办法
2万
查看次数

Python中默认参数的范围是什么?

当您使用数组参数在Python中定义函数时,该参数的范围是什么?

这个例子来自Python教程:

def f(a, L=[]):
    L.append(a)
    return L

print f(1)
print f(2)
print f(3)
Run Code Online (Sandbox Code Playgroud)

打印:

[1]
[1, 2]
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

我不太确定我是否理解这里发生的事情.这是否意味着数组的范围超出了函数的范围?为什么数组会记住从调用到调用的值?来自其他语言,只有当变量是静态的时候我才会期望这种行为.否则它似乎应该每次重置.实际上,当我尝试以下内容时:

def f(a):
    L = []
    L.append(a)
    return L
Run Code Online (Sandbox Code Playgroud)

我得到了我期望的行为(每次调用都重置了数组).

所以在我看来,我只需要def f(a, L=[]):解释这一行- L变量的范围是什么?

python parameters scope function-calls default-value

25
推荐指数
2
解决办法
3556
查看次数

为什么Python yield语句形成一个闭包?

我有两个函数返回一个函数列表.函数接受一个数字x并添加i到它.i是一个从0-9增加的整数.

def test_without_closure():
    return [lambda x: x+i for i in range(10)]



def test_with_yield():
    for i in range(10):
        yield lambda x: x+i
Run Code Online (Sandbox Code Playgroud)

我希望test_without_closure返回一个包含10个函数的列表,每个函数都添加9xi的值以来9.

print sum(t(1) for t in test_without_closure()) # prints 100
Run Code Online (Sandbox Code Playgroud)

我希望它test_with_yield也会有相同的行为,但它正确地创建了10个函数.

print sum(t(1) for t in test_with_yield()) # print 55
Run Code Online (Sandbox Code Playgroud)

我的问题是,在Python中屈服形成一个闭包吗?

python closures functional-programming yield

24
推荐指数
2
解决办法
1867
查看次数

为什么使用None修复Python的可变默认参数问题?

我正在学习Python,我正在处理Mutable Default Argument问题.

# BAD: if `a_list` is not passed in, the default will wrongly retain its contents between successive function calls
def bad_append(new_item, a_list=[]):
    a_list.append(new_item)
    return a_list

# GOOD: if `a_list` is not passed in, the default will always correctly be []
def good_append(new_item, a_list=None):
    if a_list is None:
        a_list = []
    a_list.append(new_item)
    return a_list
Run Code Online (Sandbox Code Playgroud)

我知道a_list只有在def第一次遇到语句时才初始化,这就是为什么后续调用bad_append使用相同的列表对象的原因.

我不明白的是为什么good_append有所不同.它看起来像a_list仍然只初始化一次; 因此,该if语句仅在第一次调用函数时才为真,这意味着a_list只会[]在第一次调用时重置,这意味着它仍然会累积所有过去的new_item …

python arguments function mutable

22
推荐指数
3
解决办法
4057
查看次数

向Python函数添加属性的最佳方法

以Python函数的简单情况为例,该函数计算数学函数:

def func(x, a, b, c):
    """Return the value of the quadratic function, ax^2 + bx + c."""

    return a*x**2 + b*x + c
Run Code Online (Sandbox Code Playgroud)

假设我想以函数属性的形式"附加"一些其他信息.例如,LaTeX表示.我知道,由于PEP232,我可以在函数定义之外执行此操作:

def func(x, a, b, c):
    return a*x**2 + b*x + c
func.latex = r'$ax^2 + bx + c$'
Run Code Online (Sandbox Code Playgroud)

但我想在函数定义中做到这一点.如果我写

def func(x, a, b, c):
    func.latex = r'$ax^2 + bx + c$'
    return a*x**2 + b*x + c
Run Code Online (Sandbox Code Playgroud)

这当然有效,但只有在func第一次调用之后(因为Python在执行函数时是"懒惰的"(?))

我是编写可调用类的唯一选择吗?

class MyFunction:
     def __init__(self, func, latex):
         self.func = …
Run Code Online (Sandbox Code Playgroud)

python function introspection python-3.x

20
推荐指数
2
解决办法
3326
查看次数

如何跟踪类实例?

在程序结束时,我希望将类的所有实例中的特定变量加载到字典中.

例如:

class Foo():
    __init__(self):
    x = {}

foo1 = Foo()
foo2 = Foo()
foo...etc.
Run Code Online (Sandbox Code Playgroud)

假设实例的数量会有所不同,我希望每个Foo()实例的x dict都加载到一个新的dict中.我该怎么办?

我在SO中看到的例子假设一个已经有实例列表.

python dictionary class self instances

19
推荐指数
3
解决办法
2万
查看次数

在 __init__ 中为用户类设置默认/空属性

我有不错的编程水平,并从这里的社区中获得了很多价值。然而,我从来没有在编程方面进行过太多的学术教学,也没有与真正有经验的程序员一起工作。因此,我有时会为“最佳实践”而苦恼。

对于这个问题,我找不到更好的地方,尽管可能有讨厌这些问题的喷子,我还是发布了这个。如果这让你感到不安,很抱歉。我只是想学习,而不是惹你生气。

题:

当我创建一个新类时,我是否应该在init 中设置所有实例属性,即使它们是 None 并且实际上后来在类方法中分配了值?

MyClass 的属性结果见下例:

class MyClass:
    def __init__(self,df):
          self.df = df
          self.results = None

    def results(df_results):
         #Imagine some calculations here or something
         self.results = df_results
Run Code Online (Sandbox Code Playgroud)

我在其他项目中发现,当类属性只出现在类方法中时,它们可能会被埋没,而且还有很多事情要做。

那么对于经验丰富的专业程序员来说,什么是标准做法呢?为了可读性,您会在init 中定义所有实例属性吗?

如果有人有任何关于我可以在哪里找到这些原则的材料的链接,那么请将它们放在答案中,我们将不胜感激。我知道 PEP-8 并且已经在上面搜索了我的问题好几次,但找不到任何涉及此问题的人。

谢谢

安迪

python class instance-variables instance python-attrs

19
推荐指数
2
解决办法
2万
查看次数

如何在每次迭代中获得Enum属性的随机值?

我创建了这样的Enum对象:

class Gender(Enum):
    FEMALE = 'female'
    MALE = 'male'
    RANDOM = random.choice([FEMALE, MALE])
Run Code Online (Sandbox Code Playgroud)

我想每次都获得真正的随机值,但它不起作用:

>>> class Gender(Enum):
...    MALE = 'male'
...    FEMALE = 'female'
...    RANDOM = choice([MALE, FEMALE])
... 
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>
Run Code Online (Sandbox Code Playgroud)

我也试过使用lambda,但看起来不太好,虽然它有效:

Gender.RANDOM()
Run Code Online (Sandbox Code Playgroud)

是否有其他方法可以每次获取随机值,而不使用lambda表达式?

我们使用这个枚举对象作为某个方法的参数的默认值,这就是为什么它应该是属性而不是函数,因为当我们使用Gender.FEMALE它时它不是一个函数,它是一个属性,也Gender.RANDOM应该是一个属性:

def full_name(gender=Gender.FEMALE):
    ...


def full_name(gender=Gender.RANDOM):
    ...
Run Code Online (Sandbox Code Playgroud)

python random lambda enums

18
推荐指数
3
解决办法
1855
查看次数