私信  •  关注

bruno desthuilliers

bruno desthuilliers 最近创建的主题
bruno desthuilliers 最近回复了
7 年前
回复了 bruno desthuilliers 创建的主题 » 如何使用Python计算大文件中每个数字的每次出现次数

这是Alexandru解决方案的改进版(未经测试…)(注意:Alexandru发布自己的答案时,我已经在写了这个答案,但既然他先发布了,如果它有助于解决您的问题,请给他信用)。

一般的想法是只对文件执行一次单次扫描,而不是连续执行170038(=>1441*118)次顺序扫描,并减少 sheet.write() 调用找到的行数,而不是一遍又一遍地重写同一单元格。

此外,使用函数将有助于更快的执行,因为局部变量访问比全局变量访问更快。

不知道这是否能很快解决你的问题,但至少应该 许多的 比您当前的实现速度快。

注:6米 {(int,int):int} dict很容易放在大多数现代计算机的内存中(只是在我的内存中试过,我的内存已经很忙了),所以这不是问题(而且你已经在内存中读取了整个文件,这可能是更重的wrt/内存…)

from collections import defaultdict

def parse_file():
    counts = defaultdict(int)
    with open("Data.txt") as f:
        for lineno, line in enumerate(f):
            line = line.strip()
            if not line:
                continue
            try:
                xy = tuple(int(i) for i in line.split(","))
            except (TypeError, ValueError) as e:
                print("oops, line {} is broken ? (found '{}')".format(lineno, line))
                continue
            counts[xy] += 1
    return counts


def write_counts(counts):
    book = xlsxwriter.Workbook("MyCount.xlsx")
    sheet1 = book.add_worksheet('Sheet 1')
    sheet1.write(0,0,'y\x')
    for i in range (0,1441):
       sheet1.write(0,i+1,i)
    for i in range (1,118):
        sheet1.write(i,0,i)

    for (x, y), count in counts.items():
        sheet1.write(y, x+1, count)


def main():
    counts = parse_file()
    write_counts(counts)

if __name__ == "__main__":
    main()
7 年前
回复了 bruno desthuilliers 创建的主题 » Django:在提交表单后获取最新的数据库对象值

我有一个表单,它将三个输入值保存到一个数据库,1)数字, 2)颜色,3)品牌。在我按下“提交”之后,另一个程序应该 立即显示这些值。

问题是我无法获取要显示的最新值

你做错了(而且要复杂得多)。正确的解决方案是明确地将产品id传递到“产品”视图(通过url),并在视图中重新加载对象(使用 yourmodel.objects.get(pk=...) ). 如果使用模型表单创建记录, form.save() 返回新记录,以便 在这一点上有ID(如果你只更新一个现有的产品,那么你显然已经知道了ID)。

您没有发布足够的代码/信息来从技术上解释为什么会出现这种行为,但我强烈怀疑您使用的是全局变量(或类属性),这是Django项目中导致数据陈旧的最常见原因。

另外,请注意,在刚从db获取的模型实例上调用“refresh_from_db()”主要是无用的(在这两个调用之间更新它的可能性很小),并且考虑到您的(名称不正确的)“database”函数是如何实现的,这:

number = database().number
color = database().color
make = database().make

最终 ( )对数据库的查询。

7 年前
回复了 bruno desthuilliers 创建的主题 » 在函数参数python中传递多个字典

参数是单个对象,因此 func(arg1={}, {}) 不是将两个dict作为“arg1”传递,而是将一个dict作为(命名参数)“arg1”传递,将第二个dict作为位置参数传递,正如您注意到的,python禁止在命名参数之后传递位置参数(因为它不知道位置参数将匹配哪个参数)。

如果要将多个dict作为“previous_data”和“current_data”传递,则必须传递dict的集合(在这个cas中,列表是非常明显的选择),即:

somefunc(a=[{}, {}], b=[{}, {}])

现在这也意味着您必须(重新)以这样一种方式编写您的函数:它期望的是dict列表,而不是dict列表。

7 年前
回复了 bruno desthuilliers 创建的主题 » Python:如何在一个模块中初始化对象并在另一个模块中使用它

现在,当我在mod3.py init中导入obj时,cars的方法被执行了。

当然,这是你告诉python要做的。第一次导入模块(在给定的进程中)时,将执行顶层的所有语句。你创造 obj 在mod2的顶层,所以第一次导入 mod2 , mod1 是进口的,那么 mod1.cars(...) 被称为 mod1.cars.__init__() .

我想要的是obj已经在mod2.py中初始化了,mod3应该已经初始化了实例

事情就是这样。当然,对于当前进程-对象不存在于进程之外(也不在进程之间共享)

我指的是来自不同模块的第一次导入

只要所有这些进口都在同一个过程中发生, mod2.obj 只创建一次 对于这个过程 . 当然,如果有不同的进程,每个进程都有自己的实例 OBJ -正如我所说,对象只存在于运行时,不在进程之间共享(希望如此)。

这个 只有 如果您可以使用两次导入相同的模块,则 sys.path 是混乱的,允许同一个模块名根据两个不同的限定名进行解析,并且一个导入使用一个限定名,另一个导入使用另一个限定名,但是这种情况相当少见。

7 年前
回复了 bruno desthuilliers 创建的主题 » django admin,如何只触发一次函数?

tl;dr:使用管理命令并记录安装后必须调用它的事实。

更长的答案:

能够 use the app.ready() method 要测试您的模型是否有任何记录,如果没有调用函数, 但是

  1. REST API调用很容易失败(网络问题或其他问题),这不是你想在这里发生的事情。

  2. 这也可能需要一些时间,你不想太慢的进程启动,和

  3. 可能有多个并发调用 app.ready (通常在生产设置中启动前端服务器时)并且您肯定不希望这里有竞争条件。

7 年前
回复了 bruno desthuilliers 创建的主题 » 在python中使用组合而不是继承的多态性的正确方法

你有点过分了实际上

继承描述的是一种“是”的关系,组合描述的是一种“有”的关系。所以在你的例子中,用构图来表示翅膀和腿之类的属性是非常有意义的,但是鸟、猫和狗都是动物——它们没有“拥有”动物(嗯,它们都有跳蚤,但那是另一个话题)——所以它们应该继承自 Animal .

而且,大多数鸟的腿都太长了,而且有相当一部分实际上根本不会飞(但有些鸟用腿游泳,而且很有效率)。

在对该属性调用函数之前,首先检查对象是否具有某个属性(在本例中为“legs”)是一种好的做法吗?

真的要看上下文了。作为一般规则,不,这被认为是不好的做法(参见“告诉不要问”和“德米特定律”),但有些情况下,这是合法的。而且,“好”的设计也取决于要解决的问题,我们在这里达到了玩具示例的极限,这些示例永远不能代表现实生活中的用例。

理论上,组合/委派对客户端代码应该是透明的,所以您应该只调用 whatever_animal.walk() 把它干掉。现在您(作为“客户代码”)可能想知道动物不能行走,在这种情况下,非行走动物应该提出一个例外时,收费步行…这也意味着 动物 必须有所有可能的“操作”的默认实现,并且客户机代码必须为“unsupportedAction”(或您想命名它们的方式)异常做好准备。

wrt/implementation,使委派透明可以像使用 __getattr__() 即:

class UnsupportedAction(LookupError):
    pass

class Animal(object):
    _attributes = ()

    def __init__(self, name):
        self.name = name

    def make_sound(self):
        print("silence...")

    def __getattr__(self, name):
        for att in self._attributes:
            if hasattr(att, name):
                return getattr(att, name)
        else:
            raise UnsupportedAction("{} doesn't know how to {}".format(type(self), name))



class Dog(Animal):
    _attributes = (Legs(), )


class Bird(Animal):
    _attributes = (Legs(), Wings())

这个解决方案的优点是它非常简单而且非常动态。不太好的一点是它既不可检查也不明确。

另一个解决方案是明确授权:

class UnsupportedAction(LookupError):
    pass

class Animal(object):
    _attributes = ()

    def __init__(self, name):
        self.name = name

    def make_sound(self):
        print("silence...")


    def walk(self):
        return self._resolve_action("walk")

    def fly(self):
        return self._resolve_action("walk")

    # etc            

    def _resolve_action(self, name):
        for att in self._attributes:
            if hasattr(att, name):
                return getattr(att, name)
        else:
            raise UnsupportedAction("{} doesn't know how to {}".format(type(self), name))

这是相当详细,少了很多动态,但移动明显,文件化,可读性和可检查性。

在上面的示例中,您实际上可以使用自定义描述符排除冗余代码:

class Action(object):
    def __init__(self, name):
        self.name = name

    def __get__(self, obj, cls):
        if obj is None:
            return self
        return obj._resolve_action(self.name)

    def __set__(self, obj, value):
        raise AttributeError("Attribute is readonly")


class Animal(object):
    _attributes = ()

    def __init__(self, name):
        self.name = name

    def make_sound(self):
        print("silence...")

    walk = Action("walk")
    fly = Action("fly")

    # etc

但再一次,如果没有一个真正需要解决的问题,这一切都没有意义,因为这个问题通常定义了正确的解决方案。

7 年前
回复了 bruno desthuilliers 创建的主题 » 基类中非继承属性上的python循环

一个简单、安全和有效的方法是将基类属性存储在一个不同的属性中并使用 __getattr__ 为他们服务:

class BaseClass(object):
    def __init__(self, **kwargs):
        self._attribs = kwargs

    def __getattr__(self, name):
        try:
            return self._attribs[name]
        except KeyError:
            raise AttributeError("object {} has no attribute {}".format(type(self).__name__, name))

    def calcValue(self):
        return sum(self._attribs.values())

我通常尽量避免 阿-格二氏 因为它使代码更难检查和维护,但是由于您的类已经没有明确的api,所以在这里没有太大区别。

7 年前
回复了 bruno desthuilliers 创建的主题 » django:model的@property函数的测试用例

这是一个合适的测试用例。注意,1/i为每个条件创建一个测试方法(我单独测试每个条件),2/i创建要在测试方法本身中测试的书(使测试更加明显和可读)。我只使用 setUp() 用于测试所需但不是测试本身一部分的装置。另外,我在 self.assertXXX 调用(因为将“false不是true”作为失败测试的报告并没有真正的帮助)。

class BookInstanceModelTest(TestCase):
    def setUp(self):
        self.test_user1 = User.objects.create_user(
            username='testuser1', 
            password='1X<ISRUkw+tuK',
            email='testuser1@test.com'
        )

        self.test_author = Author.objects.create(
           first_name='William', 
           last_name='Shakespeare'
        )

        self.test_book = Book.objects.create(
            title='Hamlet', 
            author=self.test_author, 
            summary='Published in 1990',                                       
            isbn='123456789123'
        )

        genre_objects_for_book = Genre.objects.all()
        self.test_book.genre.set(genre_objects_for_book)


    def test_book_is_not_overdue_if_due_back_date_is_today(self)            
        due_date = datetime.date.today()
        book = BookInstance.objects.create(
           book=self.test_book, 
           borrower=self.test_user1, 
           due_back=due_date, 
           status='o'
        )
        self.assertFalse(book.is_overdue, "book should not be overdue")


    def test_book_is_not_overdue_if_due_back_date_is_later_than_today(self):
        due_date = datetime.date.today() + datetime.timedelta(days=5)
        book = BookInstance.objects.create(
           book=self.test_book, 
           borrower=self.test_user1, 
           due_back=due_date, 
           status='o'
        )
        self.assertFalse(book.is_overdue, "book should not be overdue")


    def test_book_is_not_overdue_if_due_back_date_is_none(self):
        due_date = None
        book = BookInstance.objects.create(
           book=self.test_book, 
           borrower=self.test_user1, 
           due_back=due_date, 
           status='o'
        )
        self.assertFalse(book.is_overdue, "book should not be overdue")


    def test_book_is_overdue_if_due_back_date_is_past(self):
        due_date = datetime.date.today() - datetime.timedelta(days=5)
        book = BookInstance.objects.create(
           book=self.test_book, 
           borrower=self.test_user1, 
           due_back=due_date, 
           status='o'
        )
        self.assertTrue(book.is_overdue, "book should be overdue")
7 年前
回复了 bruno desthuilliers 创建的主题 » python全局变量不适用于新文件的用户定义函数

python“globals”只是模块的globals,没有进程范围的globals,所以 getZ.getZ() 集合 getZ.Z 不是 main2.Z . 这是设计的,这是一件好事(TM),进程范围内的全局都是纯邪恶和完全无用的。fwiw,甚至重新绑定模块globals都是有害的,应该尽可能避免(如果您重视您的心智健全,globals应该被视为常量)。

7 年前
回复了 bruno desthuilliers 创建的主题 » 使用decorator将字典插入python类

我想我可以说也许我对我的解决方案设计得太过了

嗯,确实有点…FWW the whole thing looks quite overcomplicated .

首先:如果将dict定义为全局(模块)名称,则该模块中的所有函数都可以直接访问它:

# simple.py

SHARED_DATA = {"foo": "bar", "answer": 42}

def func1():
    print SHARED_DATA["foo"]

def func2():
    print SHARED_DATA["bar"]

所以我不认为在一个从另一个模块导入的类中“注入”它只是为了从这些函数访问它。

现在和你的装饰师:

def extend(cls=BaseClass):
    def decorator(func):
        def wrapper(self, *args, **kwargs):
            return func(*args, **kwargs)
        setattr(cls, f'prefix_{func.__name__}', wrapper)
    return decorator

如果目标是使函数成为类的属性,但不将其转换为实例方法,则可以使用 staticmethod

def extend(cls=BaseClass):
    def decorator(func):
        setattr(cls, f'prefix_{func.__name__}', staticmethod(func))
        return func
    return decorator

如果你有其他(无法解释的)理由 SHARED_DICT 类属性 BaseClass 或者另一个类),您确实可以提供一个配置函数:

# module_a
def configure(cls, data):
    cls.SHARED_DATA = data


# less_simple.py

from module_a import BaseClass, configure

SHARED_DATA = {"foo": "bar", "answer": 42}
configure(BaseClass, SHARED_DATA)

def func1():
    print SHARED_DATA["foo"]

def func2():
    print SHARED_DATA["bar"]

但请注意,你仍然不需要通过 基类 也不 self 从模块的函数访问此dict。

能够 当然,可以将类或实例传递给您使用过的已定义函数,但是在这里,不需要使用奇怪的装置-要么使它们成为classmethod,要么直接将它们设置为类的属性,python将负责将类或实例作为第一个参数(这里是example使它们成为实例方法):

# module_a
def configure(cls, data):
    cls.SHARED_DATA = data

def extend(cls=BaseClass):
    def decorator(func):
        setattr(cls, f'prefix_{func.__name__}', func)
        return func
    return decorator

# rube_goldberg.py

from module_a import BaseClass, configure, extend

SHARED_DATA = {"foo": "bar", "answer": 42}
configure(BaseClass, SHARED_DATA)

@extend
def func1(self):
    print SHARED_DATA["foo"]

@extend
def func2(self):
    print SHARED_DATA["bar"]

注意,这仍然是完全无用的装饰功能pov -他们不需要 自己 完全可以进入 SHARED_DATA ,但现在如果没有 基类 实例作为第一个参数,因此用户无法直接测试它们。

现在,也许你在问题中没有提到其他的事情,但到目前为止,你似乎正在努力使简单的事情变得复杂;-)

7 年前
回复了 bruno desthuilliers 创建的主题 » 用python打印非ascii文本

首先: 你必须 read this ,没有借口

一旦完成,您就会明白,在不知道原始编码的情况下尝试将字节字符串解码为unicode通常是浪费时间。

第二点:这个(为了可读性而缩短):

u' \xc3\u201a\xc2\xa4\xc3\u201a\xc2\xbf\xc3\u0192\xc2 '

是python对unicode字符串的内部表示-通过显示字节字符串的内部表示,可以得到类似的结果:

$ python
Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = "¤¿à¤²ÃÂ"
>>> s # internal representation
'\xc3\x83\xe2\x80\x9a\xc3\x82\xc2\xa4\xc3\x83\xe2\x80\x9a\xc3\x82\xc2\xbf\xc3\x83\xc6\x92\xc3\x82 \xc3\x83\xe2\x80\x9a\xc3\x82\xc2\xa4\xc3\x83\xe2\x80\x9a\xc3\x82\xc2\xb2\xc3\x83\xc6\x92\xc3\x82'
>>> print(s) # readable output
¤¿à¤²ÃÂ

所以这里唯一的问题是混淆了内部表示和“人类可见”输出

现在请注意,字符串最终将如何显示给用户取决于进行呈现的软件(如果从命令行运行python并将其打印到stdout,则使用xterm或等效软件;如果将其呈现为服务器端生成的http响应的一部分,则使用浏览器等)和系统m设置,所有这些都不属于python的职责范围。

7 年前
回复了 bruno desthuilliers 创建的主题 » 当为模型编写时,Django信号甚至对Django-Admin也起作用。

第一点:信号用于应用间通信。要点是允许应用程序B了解应用程序A中发生的事情,而不必在任何情况下修改A。这里是您在同一个应用程序中工作的,所以 using signals here is an antipattern .

第二点: models.post_save 每当模型实例的 save() 方法是从您自己的窗体、模型管理、管理命令甚至交互shell中调用的,因此您不能根据模型的位置使用不同的信号处理程序。 保存() 已被调用。

现在解决方案很简单:不要使用信号,只需重写调用模型的save(表单的 保存() 方法,您的管理员表单 保存() 方法等),然后在这些点添加您想要的任何代码。

7 年前
回复了 bruno desthuilliers 创建的主题 » 为什么python中有属性类属性?

根据我以前的经验,类属性属于类本身,并且由所有实例共享。

这是正确的。

但是这里的weight属性是一个实例方法

不,这是一个 property 对象。当你这样做的时候:

@decorator
def func():
    return 42

它实际上是对

def func():
    return 42

func = decorator(func)

失去 def 语句被执行,函数对象被创建,但它没有绑定到它的名称,而是被传递到 decorator 可调用,并且名称绑定到 decorator() 返回。

在这种情况下,装饰师是 财产 类本身,因此 weight 属性是 财产 实例。你可以自己检查一下 LineItem.weight (将返回 财产 对象本身)。

它返回的值在实例之间是不同的。

是的,当然,这有什么奇怪的? LineItem.subtotal 也是一个类属性(和所有方法一样),但它从调用它的实例返回值(该实例作为 self 参数)。

它如何有资格成为一个类属性?对于任何实例,所有的类属性都应该是相同的,不是吗?

类属性对于类的所有实例都是相同的,是的。只有一个单人间 subtotal 函数的所有实例 LineItem .

财产 主要是使一个函数(如果指定了setter,则是一对函数)看起来像一个普通属性的快捷方式,因此当您键入 mylinitem.weight ,真正执行的是 LineItem.weight.fget(mylineitem) ,在哪里 fget 你装饰的是吸气剂的功能吗 @property . 其背后的机制称为 "descriptor protocol" ,也用于转动 mylineitem.subtotal() 进入之内 LineItem.subtotal(mylineitem) (python函数实现描述符协议以返回“method”对象,这些对象本身就是函数和当前实例的包装器,并将实例作为函数调用的第一个参数插入)。

所以属性不是类属性,你只需要一个 财产 实例为类的所有实例提供“服务”,而且,属性(如所有描述符fwiw)实际上必须是类属性才能按预期工作,因为描述符协议仅在类属性上调用(由于fu负责“计算”的NCtion将获取实例作为参数)。

7 年前
回复了 bruno desthuilliers 创建的主题 » Django临时数据存储工具

将缓存用于“临时”存储的问题是,在使用缓存之前,可能最终会将数据从缓存中取出。

既然您使用的是Postgres,那么它也是一个键值(hstore)和一个json/jsonb db。您可以在此处阅读关于这些类型的更多信息: https://www.citusdata.com/blog/2016/07/14/choosing-nosql-hstore-json-jsonb/

这仍然需要为存储使用一个表(这些是字段类型),但至少可以避免完全成熟的关系模型的负担。