小编Cea*_*sta的帖子

在Python中,何时应该使用函数而不是方法?

Python的Zen声明应该只有一种方法可以做 - 但我经常遇到决定何时使用函数与何时使用方法的问题.

让我们来看一个简单的例子 - 一个ChessBoard对象.假设我们需要一些方法来获得董事会所有合法的King移动.我们写ChessBoard.get_king_moves()或get_king_moves(chess_board)吗?

以下是我看到的一些相关问题:

我得到的答案基本上没有结果:

为什么Python使用某些功能的方法(例如list.index())但是其他功能(例如len(list))?

主要原因是历史.函数用于那些对一组类型通用的操作,这些操作甚至可以用于根本没有方法的对象(例如元组).当您使用Python的功能特性(map(),apply()等)时,拥有一个可以很容易地应用于无定形对象集合的函数也很方便.

事实上,实现len(),max(),min()作为内置函数实际上比将它们作为每种类型的方法实现它们的代码更少.人们可以对个别案例嗤之以鼻,但它是Python的一部分,现在进行这样的根本性改变为时已晚.必须保留这些功能以避免大量代码破坏.

虽然有趣,但上述内容并未真正说明采用何种策略.

这是原因之一 - 使用自定义方法,开发人员可以自由选择不同的方法名称,如getLength(),length(),getlength()或任何方法.Python强制执行严格命名,以便可以使用公共函数len().

稍微有点儿了.我的看法是函数在某种意义上是Pythonic版本的接口.

最后,来自Guido本人:

谈论能力/接口让我想到了一些我们的"流氓"特殊方法名称.在语言参考中,它说:"类可以通过定义具有特殊名称的方法来实现特殊语法(例如算术运算或下标和切片)调用的某些操作." 但是所有这些方法都有特殊的名称,__len__或者__unicode__似乎是为了内置函数的优势而提供的,而不是为了支持语法.据推测,在基于接口的Python中,这些方法将变成ABC上的常规命名方法,这样就 __len__可以了

class container:
  ...
  def len(self):
    raise NotImplemented
Run Code Online (Sandbox Code Playgroud)

虽然,再考虑一下,我不明白为什么所有语法操作都不会在特定的ABC上调用适当的常用命名方法." <"举例来说,大概会调用" object.lessthan"(或者是" comparable.lessthan").所以另一个好处是能够让Python远离这个错位名称奇怪,这在我看来是HCI的改进.

嗯.我不确定我同意(数字:-).

有两点"Python基本原理"我想首先解释一下.

首先,由于HCI的原因,我选择len(x)而不是x.len()(def __len__()后来发布).实际上有两个相互交织的原因,都是人机交互:

(a)对于某些操作,前缀表示法只比读后缀更好 - 前缀(和中缀!)操作在数学中有悠久的传统,它喜欢视觉效果帮助数学家思考问题的符号.比较与我们改写像公式简单x*(a+b)x*a + x*b使用原始OO符号做同样的事情的笨拙.

(b)当我阅读代码时,len(x)知道它是在询问某些东西的长度.这告诉我两件事:结果是一个整数,参数是某种容器.相反,当我阅读时x.len(),我必须知道这x是某种实现接口的容器或从具有标准的类继承len().当没有实现映射的类有一个get()或一个keys() 方法,或者一个不是文件的东西有一个方法时,见证我们偶尔会遇到的困惑write().

用另一种方式说同样的事情,我认为'len'是一种内置 操作 …

python methods coding-style function

107
推荐指数
5
解决办法
5万
查看次数

为什么Python的`from`形式的import语句绑定模块名称?

我有一个具有以下结构的Python项目:

testapp/
??? __init__.py
??? api
?   ??? __init__.py
?   ??? utils.py
??? utils.py
Run Code Online (Sandbox Code Playgroud)

所有模块都是空的,除了testapp/api/__init__.py它有以下代码:

from testapp import utils

print "a", utils

from testapp.api.utils import x

print "b", utils
Run Code Online (Sandbox Code Playgroud)

testapp/api/utils.py其限定x:

x = 1
Run Code Online (Sandbox Code Playgroud)

现在从我导入的根目录testapp.api:

$ export PYTHONPATH=$PYTHONPATH:.
$ python -c "import testapp.api"
a <module 'testapp.utils' from 'testapp/utils.pyc'>
b <module 'testapp.api.utils' from 'testapp/api/utils.pyc'>
Run Code Online (Sandbox Code Playgroud)

导入的结果让我感到惊讶,因为它表明第二个import语句已被覆盖utils.然而,文档声明from语句不会绑定模块名称:

from表单不绑定模块名称:它遍历标识符列表,在步骤(1)中找到的模块中查找每个标识符,并将本地名称空间中的名称绑定到找到的对象.

事实上,当我在终端中使用from ... import ...语句时,不会引入任何模块名称:

>>> from os.path import abspath
>>> …
Run Code Online (Sandbox Code Playgroud)

python import

24
推荐指数
1
解决办法
344
查看次数

如何更改实例的dict()行为

所以我正在编写一个扩展字典的类,该字典现在使用一种方法"dictify"将自身转换为字典.我想做的是改变它,以便在对象上调用dict()导致相同的行为,但我不知道要覆盖哪个方法.这是不可能的,还是我错过了一些完全明显的东西?(是的,我知道下面的代码不起作用,但我希望它能说明我正在尝试做什么.)

from collections import defaultdict

class RecursiveDict(defaultdict):
    '''
    A recursive default dict.

    >>> a = RecursiveDict()
    >>> a[1][2][3] = 4
    >>> a.dictify()
    {1: {2: {3: 4}}}
    '''
    def __init__(self):
        super(RecursiveDict, self).__init__(RecursiveDict)

    def dictify(self):
        '''Get a standard dictionary of the items in the tree.'''
        return dict([(k, (v.dictify() if isinstance(v, dict) else v))
                     for (k, v) in self.items()])

    def __dict__(self):
        '''Get a standard dictionary of the items in the tree.'''
        print [(k, v) for (k, v) in self.items()]
        return dict([(k, (dict(v) if …
Run Code Online (Sandbox Code Playgroud)

python dictionary overriding autovivification

18
推荐指数
1
解决办法
5453
查看次数

如何测试Python函数装饰器?

我正在尝试编写单元测试以确保我编写的各种装饰器的正确性.这是我正在尝试编写的代码的开头:

import unittest

from memoizer import Memoizer
from strategies.mru import MRU


@Memoizer(strategy=MRU(maxsize=10))
def fib(x):
  if x < 2:
    return 1
  else:
    return fib(x-1) + fib(x-2)


class TestMemoizer(unittest.TestCase):

  def test_simple(self):
    self.assertEqual(fib(0), 1)
    self.assertEqual(fib(1), 1)
    self.assertEqual(fib(10), 89)


if __name__ == '__main__':
  unittest.main()
Run Code Online (Sandbox Code Playgroud)

虽然这对我上面提到的MRU策略很有效,但我计划编写其他策略,在这种情况下我需要以不同的方式用fib函数进行装饰.(回想一下,因为fib调用fib,设置fib2 = memoize(fib)不会记忆中间值,因此不起作用.)测试其他装饰器的正确方法是什么?

python unit-testing decorator

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

如何阻止CORB阻止对以CORS标头响应的数据资源的请求?

我正在开发一个Chrome扩展程序,该扩展程序可以将某些网站的请求发送到我控制的API。直到Chrome 73,该扩展程序才能正常工作。升级到Chrome 73之后,我开始出现以下错误:

跨域读取阻止(CORB)使用MIME类型application / json 阻止了跨源响应 http:// localhost:3000 / api / users / 1

根据Chrome关于CORB的文档,如果满足以下所有条件,则CORB将阻止请求的响应:

  1. 该资源是“数据资源”。具体来说,内容类型为HTML,XML,JSON

  2. 服务器以X-Content-Type-Options: nosniff标头作为响应,或者如果省略标头,则Chrome通过检查文件来检测内容类型是HTML,XML还是JSON之一

  3. CORS不允许显式访问资源

另外,根据“从幽灵和熔化的教训”(谷歌I / O 2018) ,现在看来似乎可能增加是重要的mode: cors,以fetch调用,即fetch(url, { mode: 'cors' })

为了解决此问题,我进行了以下更改:

首先,我向API的所有响应添加了以下标头:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Origin: https://www.example.com
Run Code Online (Sandbox Code Playgroud)

其次,我fetch()将扩展名的调用更新为如下形式:

fetch(url, { credentials: 'include', mode: 'cors' })
Run Code Online (Sandbox Code Playgroud)

但是,这些更改不起作用。我该如何更改以使我的请求不会被CORB阻止?

google-chrome google-chrome-extension cors cross-origin-read-blocking

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

Python范围函数在实际函数之前是如何具有默认参数的?

所以我正在编写一个带有可选列表的函数,并将其扩展到指定的长度.而不是将其写为foo(n,list = None),我想知道如何模拟Python的范围函数的行为,其工作方式如下:

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(5, 10)
[5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

也就是说,首先使用默认参数.为了参考试图天真地设置它返回一个语法错误:

def foo(x=10, y):
    return x + y
SyntaxError: non-default argument follows default argument
Run Code Online (Sandbox Code Playgroud)

所以我想知道,这是硬编码到范围内吗?或者可以模仿这种行为?

python overloading range default-value

11
推荐指数
4
解决办法
4970
查看次数

如何使用Google GSON将JSON数组反序列化为泛型类型的集合?

我正在编写一些代码,用于从网站中检索资源.它看起来像这样:

public Collection<Project> getProjects() {
        String json = getJsonData(methods.get(Project.class)); //Gets a json list, ie [1, 2, 3, 4]
        Gson gson = new Gson();
        Type collectionType = new TypeToken<Collection<Project>>() {}.getType();
        return gson.fromJson(json, collectionType);
    }
Run Code Online (Sandbox Code Playgroud)

所以我很自然地尝试使用Java泛型来抽象它.

/*
     * Deserialize a json list and return a collection of the given type.
     * 
     * Example usage: getData(AccountQuota.class) -> Collection<AccountQuota>
     */
    @SuppressWarnings("unchecked")
    public <T> Collection<T> getData(Class<T> cls) {
        String json = getJsonData(methods.get(cls)); //Gets a json list, ie [1, 2, 3, 4]
        Gson gson = new …
Run Code Online (Sandbox Code Playgroud)

java generics gson

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

从另一个视图调用我的服务器上的API

所以,这里有一种奇怪的情况.我有一个Django项目,使用TastyPie为其API和一些视图/模板提供动力,这些视图/模板将用于为各种站点提供插件.我没有将这个插件构建为标准的Django模板,而是被要求使用我们的API来处理对插件的请求,这意味着我从另一个视图调用我的服务器上的视图,并且由于某些原因无效我的任何观点.以供参考:

#views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template.context import Context, RequestContext
import json, urllib, urllib2

SITE_NAME = "http://localhost:8000/"
API_PATH = "api/v1/"

def aggregate(request):
    template = 'lemonwise/plugins/aggregate.html'
    sku = request.GET.get('sku')
    url = ''.join([SITE_NAME, API_PATH, 'product/?sku=', sku])
    product = json.loads(urllib.urlopen(url).read())['objects'][0]
    return render_to_response(template, product)

def reviews(request):
    template = 'lemonwise/plugins/reviews.html'
    sku = request.GET.get('sku')
    url = ''.join([SITE_NAME, API_PATH, 'product/?format=json&sku=', sku])
    #Comment the next line out and the url is passed correctly
    response = urllib2.build_opener().open(url).read()
    return HttpResponse(url)
    #page = opener.open(url).read()
    #return HttpResponse(url) …
Run Code Online (Sandbox Code Playgroud)

api django view

9
推荐指数
1
解决办法
3904
查看次数

描述符'getter'需要'property'对象但是收到'function'

所以我在下面有一个Table对象的代码,它有一个fieldnames属性.

class Table(object):
    '''A CSV backed SQL table.'''
    @property
    def fieldnames(self):
        with open(self.filename) as f:
            return csv.DictReader(f).fieldnames

    @property.setter
    def fieldnames(self, fieldnames):
        with open(self.filename, 'w') as f:
            dr = csv.reader(f)
            dw = csv.DictWriter(f, fieldnames=fieldnames)
            dw.writerow(dict((field, field) for field in fieldnames))
            for row in self:
                dw.writerow(row)
Run Code Online (Sandbox Code Playgroud)

当我尝试导入文件时,我收到错误:

seas486:PennAppSuite ceasarbautista$ python
Python 2.7.1 (r271:86832, Jun 25 2011, 05:09:01) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import table …
Run Code Online (Sandbox Code Playgroud)

python setter properties decorator

9
推荐指数
1
解决办法
2887
查看次数

为什么C打印我的十六进制值不正确?

所以我对C来说是一个新手,我很想知道为什么我会得到这种不寻常的行为.

我一次读取16位文件,然后按如下方式打印出来.

#include <stdio.h>

#define endian(hex) (((hex & 0x00ff) << 8) + ((hex & 0xff00) >> 8))

int main(int argc, char *argv[])
 {
  const int SIZE = 2;
  const int NMEMB = 1;
  FILE *ifp; //input file pointe
  FILE *ofp; // output file pointer

  int i;
  short hex;
  for (i = 2; i < argc; i++)
   {
    // Reads the header and stores the bits
    ifp = fopen(argv[i], "r");
    if (!ifp) return 1;
    while (fread(&hex, SIZE, NMEMB, ifp))
     {
      printf("\n%x", …
Run Code Online (Sandbox Code Playgroud)

c

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