小编Mar*_*nen的帖子

为什么`if`在语句之前检查比在语句之后检查要快得多?

这是我的意思的一个例子:

s = """
if x > 10:
    x -= 10
else:
    x = 0
"""
import timeit
print(timeit.timeit(s, setup="x=5", number=99999999))
Run Code Online (Sandbox Code Playgroud)

在我的电脑上输出大约3秒钟,无论设置如何(x=5vs x=15,没有区别)


如果我要使用更短的代码,首先减少代码,x -= 10然后再检查是否x < 0,我会得到更糟糕的结果:

s = """
x -= 10
if x < 0:
    x = 0
"""
import timeit
print(timeit.timeit(s, setup="x=5", number=99999999))
Run Code Online (Sandbox Code Playgroud)

它6秒输出各处,再次不管初始值是否x515.


我知道,x < 10自从我们第一次打电话x -= 10然后设置x = 0而不是简单地设置x一次就会慢一点.

问题是,99%的时间x我的程序中的初始值被设置为远高于10的数字,所以我认为我会使用较短的版本,因为大多数时候我应该看不出性能上的差异.

然而,即使是 …

python performance performance-testing python-3.x

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

阻止从子类访问实例变量,而不影响基类

假设我有一个简单的类Foo,它来自外部库,因此我无法直接更改它:

class Foo(object):
    def __init__(self, x):
        self.x = x
Run Code Online (Sandbox Code Playgroud)

我想创建一个子类Bar并防止x从实例中更改Bar,但仍然使用xin Bar的方法.

这是我尝试过的,它可能会启发基本的想法,但不幸的是它不起作用:

class Bar(Foo):

    @property
    def x(self):
        return super().x

    @x.setter
    def x(self, value):
        raise NotImplementedError('Do not change x directly, use "do_stuff()" instead')

    def do_stuff(self, value):
        if <something>:
            super().x = value
Run Code Online (Sandbox Code Playgroud)

所以基本上我已经do_stuff()在一个属性周围创建了一些包装函数(),现在我想防止直接更改属性,因为它可能会破坏包装函数的某些功能.这有可能以合理的方式吗?

编辑了我想要的更好的例子.我不是想阻止他们看到变量x,而是从外面改变它do_stuff()

python inheritance class python-3.x

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

为什么旧样式类的实例是`object`的实例?

在Python 2中,为什么旧​​样式类的实例仍然是实例,object即使它们没有显式继承object

class OldClass:
    pass

>>> isinstance(OldClass(), object)
True
Run Code Online (Sandbox Code Playgroud)

在测试之前,我会得出结论,isinstance(x, object) == True这意味着它x是一个子类object的实例,因此是新样式类的一个实例,但似乎Python 2中的所有对象都是实例object(是的,我知道声音有多明显) ).


进一步挖掘,我发现了一些看似奇怪的行为:

>>> issubclass(OldClass, object)
False
Run Code Online (Sandbox Code Playgroud)

我的印象isinstance(x, SomeClass)实际上相当于issubclass(x.__class__, SomeClass),但显然我错过了一些东西.

python class python-2.x isinstance python-internals

9
推荐指数
0
解决办法
227
查看次数

如何将SQLAlchemy与类属性(和属性)一起使用?

假设我正在制作带有物品的游戏(想想Minecraft,CS:GO武器,LoL和Dota物品等).游戏中可能存在大量相同的项目,但细节差异很小,例如条件/耐久性或项目中剩余的弹药数量:

player1.give_item(Sword(name='Sword', durability=50))
player2.give_item(Sword(name='Sword', durability=80))
player2.give_item(Pistol(name='Pistol', ammo=12))
Run Code Online (Sandbox Code Playgroud)

但是因为我不想每次都给我的剑和手枪命名(由于名字总是相同的),我希望它能够非常容易地创建新的项目类,我想我会name上课属性:

class Item:
    name = 'unnamed item'
Run Code Online (Sandbox Code Playgroud)

现在我只是将其子类化:

class Sword(Item):
    name = 'Sword'

    def __init__(self, durability=100):
        self.durability = durability

class Pistol(Item):
    name = 'Pistol'

    def __init__(self, ammo=10):
        self.ammo = ammo
Run Code Online (Sandbox Code Playgroud)

我们有工作班:

>>> sword = Sword(30)
>>> print(sword.name, sword.durability, sep=', ') 
Sword, 30
Run Code Online (Sandbox Code Playgroud)

但有没有办法以这种或那种方式使用SQLAlchemy 这些类属性(有时甚至是classproperties)?比如,我想将项目的持久性(实例属性)和名称(类属性)与其class_id(类属性)作为主键存储:

class Item:
    name = 'unnamed item'

    @ClassProperty  # see the classproperty link above
    def class_id(cls):
        return cls.__module__ + '.' + cls.__qualname__

class Sword(Item): …
Run Code Online (Sandbox Code Playgroud)

python sqlalchemy properties class-attributes python-3.x

8
推荐指数
1
解决办法
2635
查看次数

使用只读列获取相同值的只读属性

游戏引擎为我提供了一个Player具有uniqueid只读属性的类来识别玩家.我想将其"转换"为SQLAlchemy,Column以便我可以像这样查询玩家:

query = session.query(Player).filter(Player.uniqueid=='STEAM_0:0:1234567')
player = query.one_or_none()
if player is None:
    player = Player(uniqueid='STEAM_0:0:1234567')
Run Code Online (Sandbox Code Playgroud)

这是我班级目​​前的样子:

class Player(game.Player, db.Model):
    _uniqueid = Column('uniqueid', String(21), unique=True, nullable=False)

    def __init__(self, index, **kwargs):
        game.Player.__init__(index)  # initializes uniqueid
        db.Model.__init__(_uniqueid=self.uniqueid, **kwargs)
Run Code Online (Sandbox Code Playgroud)

接下来我想为它创建一个只读接口_uniqueid,因此API用户不能再写入变量(好吧,他们可以通过_uniqueid,但这是他们的责任,因为访问它应该通过非私有uniqueid).

我想uniqueid用一个新原件覆盖原件:

@property
def uniqueid(self):
    return self._uniqueid
Run Code Online (Sandbox Code Playgroud)

这是只读的并且"隐藏"原件_uniqueid,阻止任何人写入它,除非他们故意访问私有(我甚至不会在文档中列出它,我只会暴露非私有的).

唯一的问题是,这完全取代旧的,这意味着由于使用新的吸气剂而不是旧的吸气剂,我__init__的功能_uniqueid=self.uniqueid无法self.uniqueid使用.

总而言之,我想要的是将只读属性转换为可用于使用SQLAlchemy查询的只读属性.这是可能的,如果,如何?

python sqlalchemy python-3.x

8
推荐指数
1
解决办法
254
查看次数

在自己的体内更改函数的属性?

我正在尝试创建一个函数来记录它被调用的次数,我希望信息保留在函数本身内部.我试着像这样创建一个包装器:

def keep_count(f):
    f.count = 0
    @functools.wraps(f)
    def wrapped_f(*args, **kwargs):
        f(*args, **kwargs)
        f.count += 1
    return wrapped_f

@keep_count
def test_f(*args, **kwargs):
    print(args, kwargs)
Run Code Online (Sandbox Code Playgroud)

我认为它有用,但我有一个AttributeError说法'function' object has no attribute 'count'.

我已经想到了问题:这是因为装饰器将我设置test_f为等于wrapped_f(在keep_count装饰器内部定义),并且我增加了原始的计数,f因为它test_f引用了新函数,所以不再使用它.

有没有办法在没有太多黑客攻击的情况下做到这一点?

python function decorator python-3.x

7
推荐指数
1
解决办法
114
查看次数

修改冷却装饰器以用于方法而不是函数

我正在尝试创建一个装饰器,它可以用于对它们应用"冷却"的方法,这意味着它们不能在一定的持续时间内被多次调用.我已经为函数创建了一个:

>>> @cooldown(5)
... def f():
...     print('f() was called')
...
>>> f()
f() was called
>>> f()  # Nothing happens when called immediately
>>> f()  # This is 5 seconds after first call
f() was called
Run Code Online (Sandbox Code Playgroud)

但是我需要这个来支持类的方法而不是普通的函数:

>>> class Test:
...    @cooldown(6)
...    def f(self, arg):
...        print(self, arg)
...
>>> t = Test()
>>> t.f(1)
<Test object at ...> 1
>>> t.f(2)
>>> t.f(5)  # Later
<Test object at ...> 5
Run Code Online (Sandbox Code Playgroud)

这是我创建的,使其适用于正常功能:

import time

class _CooldownFunc:
    def __init__(self, …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-decorators

7
推荐指数
1
解决办法
354
查看次数

在PostgreSQL上使用SQLAlchemy创建全文搜索索引

我需要使用SQLAlchemy在Python中创建PostgreSQL全文搜索索引.这是我想要的SQL:

CREATE TABLE person ( id INTEGER PRIMARY KEY, name TEXT );
CREATE INDEX person_idx ON person USING GIN (to_tsvector('simple', name));
Run Code Online (Sandbox Code Playgroud)

现在,在使用ORM时,如何使用SQLAlchemy执行第二部分:

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
Run Code Online (Sandbox Code Playgroud)

python postgresql sqlalchemy python-3.x flask-sqlalchemy

7
推荐指数
4
解决办法
3136
查看次数

初始化期间为namedtuple字段键入转换

我有一个几乎没有静态字段的类,并且可以从iterable初始化(比如输出csvreader).在__init__从字符串到数字对于他们中的一些进行类型转换:

class PerformanceTestResult(object):
    def __init__(self, csv_row):
        # csv_row[0] is just an ordinal number of the test - skip that
        self.name = csv_row[1]          # Name of the performance test
        self.samples = int(csv_row[2])  # Number of measurement samples taken
        self.min = int(csv_row[3])      # Minimum runtime (ms)
        self.max = int(csv_row[4])      # Maximum runtime (ms)
        self.mean = int(csv_row[5])     # Mean (average) runtime (ms)
        self.sd = float(csv_row[6])     # Standard deviation (ms)
Run Code Online (Sandbox Code Playgroud)

我正在考虑将它转换为a namedtuple,因为它没有太多其他内容.但我想在初始化期间保持类型转换.有没有办法做到这一点namedtuple?(我没有注意到工厂方法__init__的详细输出中的namedtuple方法,这让我暂停了默认初始化程序的工作原理.)

python namedtuple iterable-unpacking

7
推荐指数
1
解决办法
810
查看次数

使用if检查重载函数以获取true_type或false_type参数?

与使用一个语句相比,使用方法/函数重载true_typefalse_type参数是否有任何好处if?我看到越来越多的代码使用重载方法true_typefalse_type参数.

使用if语句的简短示例

void coutResult(bool match)
{
    if (match)
        cout << "Success." << endl;
    else
        cout << "Failure." << endl;
}

bool match = my_list.contains(my_value);
coutResult(match);
Run Code Online (Sandbox Code Playgroud)

与使用重载函数相比:

void coutResult(true_type)
{
    cout << "Success." << endl;
}

void coutResult(false_type)
{
    cout << "Failure." << endl;
}

bool match = my_list.contains(my_value);
coutResult(match);
Run Code Online (Sandbox Code Playgroud)

c++ boolean overloading

6
推荐指数
1
解决办法
3944
查看次数