2

私はPythonを学ぶ最初の一歩を踏み出し始め、クラスの使用を開始しようとしています.

これまでのところ、この簡略化されたバージョンがあります。

class ThingsInTheFridge(object):
  def __init__(self):
    self.milk = False
    self.yogurt = False
    self.bread = True
    self.umbrella = True

私のクラスには約 30 のものがあり、それぞれに True または False が割り当てられます (この質問のリストを短くしました)。

それらを割り当てる最も効率的な方法は何ですか?

私はこれについて考えましたが、特にリストのサイズが大きくなった場合は改善されないようです:

self.milk, self.yogurt = False, False

編集: クラスには他の項目があることに言及する必要があったかもしれません (問題になるとは思わなかったので省略しました):

class ThingsInTheFridge(object):
  def __init__(self):
    self.milk = False
    self.yogurt = False
    self.bread = True
    self.umbrella = True
    self.bulb = "maker name"
    self.shoes = 2
4

4 に答える 4

4

実行時の効率を本当に気にしているなら、ほぼ確実に間違った場所を探しています。メンバーの初期化に時間がかかりすぎる場合 (可能性は非常に低いですが、プロファイリングしてこれがホットスポットであることがわかった場合は…)、正しい答えは を使用する__slots__ことであり、初期化の方法を変更することではありません。

プログラマーの効率 (読みやすさ、およびそれほどではないが書き込みやすさ) を気にする場合は、いつでもこれを行うことができます。

self.milk = self.yogurt = False

より動的に物事を行いたい場合は、 で次のようなことを行うことができますが、setattrお勧めしません:

class ThingsInTheFridge(object):
    false_things = ('bread', 'umbrella')
    true_things = ('milk', 'yogurt')
    def __init__(self):
        for thing in ThingsInTheFridge.false_things:
            setattr(self, thing, False)
        for thing in ThingsInTheFridge.true_things:
            setattr(self, thing, True)

お勧めしない理由は、このレベルで動的に物事を行う必要がある場合は、おそらくアクセスレベルでdictも動的にする必要があるためsetです。

クラス スタイル システムの上にプロトタイプ スタイルのオブジェクト指向システムを構築したり、クラス情報に基づいてインスタンスを初期化するメタクラスを作成したりすることもできますが、この文の冒頭で示されているように、それは船外に出ます。

于 2013-02-04T19:30:38.743 に答える
4

これは、データを保存するモデルに問題があることを示していると思います。おそらく、属性だけでなく、セットのようなデータ構造を使用したいと思うでしょう。

例えば:

items = {"milk", "yogurt", "bread", "umbrella"}
stored = set()

次に、必要なものをセットに保存しますstored"milk" in storedセットは、メンバーシップ チェックのパフォーマンスが非常に高速であるため、チェックするには、たとえばを実行するだけです。

持っているインターフェイスを本当に維持したい場合は__getattr__()、属性を要求したときに取得するアクションをオーバーライドするために使用できます。

def ___getattr__(self, item):
    return item in self.stored

False可能性のあるアイテムにのみ応答する必要がある場合、これは冷蔵庫にないものに戻ります。これは簡単に実行できます。

def ___getattr__(self, item):
    if item not in self.items:
        raise AttributeError
    return item in self.stored

当然、設定も行うことができます。

def __setattr__(self, item, value):
    if item in self.items:
        if value:
            self.stored.add(item)
        else:
            self.stored.remove(item)
    else:
        ...

これに代わるものはTrue/への口述Falseです - どちらかが特に優れているとは言えませんが、あなたのプロジェクトにより適しているかもしれません。自分に最適なものを使用してください。

于 2013-02-04T19:31:18.460 に答える
1

あなたの主な焦点は、読みやすさと基礎となるデータ構造であるべきだと思います。

このようなものは非常に読みやすく、(おそらく) 所有するローリングによって達成できるのと同じくらい高いパフォーマンスです:

from collections import Counter

class Fridge(object):
    def __init__(self,things,name):
        self.things=Counter(things)
        self.wanted=set()
        self.name=name

    def look(self, thing):
        print 'There are {} {} in {}'.format(self.things[thing],thing,self.name)

    def stare_inside(self):
        cathave=sorted([(co,it) for it,co in self.things.items() if co])
        print '{} items in {}:'.format(len(cathave),self.name)
        for i, item in enumerate(cathave,1):
            print '   {}: {} -- {}'.format(i,item[1],item[0])

    def shop(self):
        shop_list=[it for it,co in self.things.items() if co==0]
        for item in shop_list:
            del self.things[item]
        shop_list.extend(list(self.wanted))
        self.wanted=set()
        print "shopping list:"
        for i, item in enumerate(sorted(shop_list),1):
            print '   {}: {}'.format(i,item)    

    def consume(self,thing,count):
        if self.things[thing]>=count:
            self.things[thing]-=count   
        else: 
            print 'Not enough {} to consume {} -- {} in the {}.'.format(
                  thing,count,self.things[thing],self.name)
            self.wanted.add(thing)

    def stock(self,things):
        self.things+=Counter(things)

今すぐ試してください:

>>> kitchen=Fridge({'coke':2, 'whole milk':1,'ketchup':1, 'anchovies':24},'kitchen fridge')
>>> kitchen.look('coke')
There are 2 coke in kitchen fridge
>>> kitchen.stock({'coke':1,'pepsi':2,'banana':3})
>>> kitchen.stare_inside()
6 items in kitchen fridge:
   1: ketchup -- 1
   2: whole milk -- 1
   3: pepsi -- 2
   4: banana -- 3
   5: coke -- 3
   6: anchovies -- 24
>>> kitchen.consume('red bull',22)
Not enough red bull to consume 22 -- 0 in the kitchen fridge.
>>> kitchen.consume('coke',3)
>>> kitchen.consume('whole milk',1)
>>> kitchen.stare_inside()
4 items in kitchen fridge:
   1: ketchup -- 1
   2: pepsi -- 2
   3: banana -- 3
   4: anchovies -- 24
>>> kitchen.shop()
shopping list:
   1: coke
   2: red bull
   3: whole milk

これは、コレクション モジュールの Counter クラスに基づいています。より高速なネイティブ Python を思い付く可能性は低いです。

于 2013-02-04T20:12:15.633 に答える
0

実際には、個々のフラグ メンバーの代わりに一連の文字列を使用した方がよい場合があります。次のようなものは、あなたがやろうとしているように見えるものによりうまくいくかもしれません.

class ThingsInTheFridge:
    """I represent a collection of items in a refrigerator.

    I contain a few things by default.  You can add and remove items as
    well as test for membership.

    >>> things = ThingsInTheFridge()
    >>> object() in things
    False
    >>> things.store_item('foo')
    >>> 'foo' in things
    True
    """
    def __init__(self):
        self._items = set()
        self.store_item('bread')
        self.store_item('umbrella')
    def store_item(self, item):
        """Add an item to the fridge.
        :param item: the item to add.

        Items are coerced into strings and normalized before they are
        added to the internal list.

        >>> things = ThingsInTheFridge()
        >>> things.store_item(False)
        >>> 'false' in things
        True
        >>> 'FALSE' in things
        True
        >>> False in things
        True
        """
        self._items.add(str(item).lower())
    def __contains__(self, item):
        """Check if an item is in the fridge.
        :param item: item to check for.

        Items are coerced into strings and normalized to match the processing
        in :py:meth:`store_item`.

        >>> things = ThingsInTheFridge()
        >>> things.store_item('Milk')
        >>> 'Milk' in things, 'milk' in things, 'MiLk' in things
        (True, True, True)
        """
        return str(item).lower() in self._items
于 2013-02-04T19:56:29.960 に答える