Pythonic способы 'еще' использовать в для цикла

В дополнение к перестройке ядра, вы также можете использовать kallsyms_lookup_name , чтобы найти адрес, соответствующий символу

, например ниже:

#include <linux/module.h>
#include <linux/mm.h>
#include <linux/kallsyms.h>

MODULE_LICENSE("GPL");

unsigned long (*orig_do_mmap)(struct file *file, unsigned long addr,
                              unsigned long len, unsigned long prot,
                              unsigned long flags, vm_flags_t vm_flags,
                              unsigned long pgoff, unsigned long *populate,
                              struct list_head *uf);

static int __init hp_km_init(void)
{
    orig_do_mmap = (void*)kallsyms_lookup_name("do_mmap");
    if (orig_do_mmap == NULL)
        return -EINVAL;

    orig_do_mmap(0, 0, 0, 0, 0, 0, 0, 0, 0);
    return 0;
}

static void __exit hp_km_exit(void)
{
}

module_init(hp_km_init);
module_exit(hp_km_exit);
13
задан SilentGhost 26 March 2009 в 13:28
поделиться

6 ответов

Каково могло быть больше pythonic, чем PyPy?

Посмотрите на то, что я обнаружил запуск в строке 284 в ctypes_configure/configure.py:

    for i in range(0, info['size'] - csize + 1, info['align']):
        if layout[i:i+csize] == [None] * csize:
            layout_addfield(layout, i, ctype, '_alignment')
            break
    else:
        raise AssertionError("unenforceable alignment %d" % (
            info['align'],))

И здесь, от строки 425 в pypy/annotation/annrpython.py (clicky)

if cell.is_constant():
    return Constant(cell.const)
else:
    for v in known_variables:
        if self.bindings[v] is cell:
            return v
    else:
        raise CannotSimplify

В pypy/annotation/binaryop.py, запускающемся в строке 751:

def is_((pbc1, pbc2)):
    thistype = pairtype(SomePBC, SomePBC)
    s = super(thistype, pair(pbc1, pbc2)).is_()
    if not s.is_constant():
        if not pbc1.can_be_None or not pbc2.can_be_None:
            for desc in pbc1.descriptions:
                if desc in pbc2.descriptions:
                    break
            else:
                s.const = False    # no common desc in the two sets
    return s

Неострота в pypy/annotation/classdef.py, запускающемся в строке 176:

def add_source_for_attribute(self, attr, source):
    """Adds information about a constant source for an attribute.
    """
    for cdef in self.getmro():
        if attr in cdef.attrs:
            # the Attribute() exists already for this class (or a parent)
            attrdef = cdef.attrs[attr]
            s_prev_value = attrdef.s_value
            attrdef.add_constant_source(self, source)
            # we should reflow from all the reader's position,
            # but as an optimization we try to see if the attribute
            # has really been generalized
            if attrdef.s_value != s_prev_value:
                attrdef.mutated(cdef) # reflow from all read positions
            return
    else:
        # remember the source in self.attr_sources
        sources = self.attr_sources.setdefault(attr, [])
        sources.append(source)
        # register the source in any Attribute found in subclasses,
        # to restore invariant (III)
        # NB. add_constant_source() may discover new subdefs but the
        #     right thing will happen to them because self.attr_sources
        #     was already updated
        if not source.instance_level:
            for subdef in self.getallsubdefs():
                if attr in subdef.attrs:
                    attrdef = subdef.attrs[attr]
                    s_prev_value = attrdef.s_value
                    attrdef.add_constant_source(self, source)
                    if attrdef.s_value != s_prev_value:
                        attrdef.mutated(subdef) # reflow from all read positions

Позже в том же файле, запускающемся в строке 307, пример с освещающим комментарием:

def generalize_attr(self, attr, s_value=None):
    # if the attribute exists in a superclass, generalize there,
    # as imposed by invariant (I)
    for clsdef in self.getmro():
        if attr in clsdef.attrs:
            clsdef._generalize_attr(attr, s_value)
            break
    else:
        self._generalize_attr(attr, s_value)
15
ответ дан 1 December 2019 в 20:44
поделиться

Если Вы имеете для цикла, у Вас действительно нет оператора условия. Таким образом, повреждение является Вашим выбором, если Вы любите прерываться и затем еще можете служить отлично для обработки случая, где Вы не были счастливы.

for fruit in basket:
   if fruit.kind in ['Orange', 'Apple']:
       fruit.eat()
       break
else:
   print 'The basket contains no desirable fruit'
6
ответ дан 1 December 2019 в 20:44
поделиться

Без использования break, else блоки не обладают никаким преимуществом для for и while операторы. Следующий двум примерам эквивалентен:

for x in range(10):
  pass
else:
  print "else"

for x in range(10):
  pass
print "else"

Единственная причина использования else с for или while должен сделать что-то после цикла, если бы он обычно завершался, означая без явного break.

После большого количества взглядов я могу наконец придумать случай, где это могло бы быть полезно:

def commit_changes(directory):
    for file in directory:
        if file_is_modified(file):
            break
    else:
        # No changes
        return False

    # Something has been changed
    send_directory_to_server()
    return True
3
ответ дан 1 December 2019 в 20:44
поделиться

Возможно, лучший ответ прибывает из официального учебного руководства Python:

повредите и продолжите Операторы и выражения else на Циклах:

Инструкции циклов могут иметь выражение else; это выполняется, когда цикл завершается посредством исчерпания списка (с для) или когда условие становится ложью (с в то время как), но не, когда цикл завершается оператором завершения

2
ответ дан 1 December 2019 в 20:44
поделиться

Вот:

a = ('y','a','y')
for x in a:
  print x,
else:
  print '!'

Это для камбуза.

править:

# What happens if we add the ! to a list?

def side_effect(your_list):
  your_list.extend('!')
  for x in your_list:
    print x,

claimant = ['A',' ','g','u','r','u']
side_effect(claimant)
print claimant[-1]

# oh no, claimant now ends with a '!'

править:

a = (("this","is"),("a","contrived","example"),("of","the","caboose","idiom"))
for b in a:
  for c in b:
    print c,
    if "is" == c:
      break
  else:
    print
-1
ответ дан 1 December 2019 в 20:44
поделиться

В принципе, это упрощает любой цикл, в котором используется булевый флаг типа:

found = False                # <-- initialize boolean
for divisor in range(2, n):
    if n % divisor == 0:
        found = True         # <-- update boolean
        break  # optional, but continuing would be a waste of time

if found:                    # <-- check boolean
    print n, "is composite"
else:
    print n, "is prime"

и позволяет пропустить управление флагом:

for divisor in range(2, n):
    if n % divisor == 0:
        print n, "is composite"
        break
else:
    print n, "is prime"

Обратите внимание, что уже есть естественное место для выполнения кода, когда вы находите делитель - прямо перед break. Единственное новшество здесь - это место для выполнения кода, когда вы перепробовали все делители и не нашли ни одного.

Это помогает только в сочетании с break. Вам все равно нужен булеан, если вы не можете сломаться (например, из-за того, что ищете последнее совпадение, или вынуждены отслеживать несколько условий параллельно)

О, и BTW, это работает на время циклов также хорошо.

any/all

Nowdays, если единственной целью цикла является ответ "да" или "нет", вы можете записать его намного короче с помощью функций any()/all() с генератором или выражением генератора, которое дает булеан:

if any(n % divisor == 0 
       for divisor in range(2, n)):
    print n, "is composite"
else:
    print n, "is prime"

Обратите внимание на элегантность! Код 1:1 - это то, что вы хотите сказать!

[Это так же эффективно, как и цикл с перерывом , потому что функция any() имеет короткое замыкание, выполняя выражение генератора только до тех пор, пока оно не загорится True. На самом деле, обычно это даже быстрее, чем цикл. Простой код на Python имеет тенденцию меньше подслушивать.]

Это менее работоспособно, если у Вас есть другие побочные эффекты - например, если Вы хотите найти делитель. Вы все еще можете сделать это (ab)используя тот факт, что не 0 значение верно на Python:

divisor = any(d for d in range(2, n) if n % d == 0)
if divisor:
    print n, "is divisible by", divisor
else:
    print n, "is prime"

но, как видите, это становится шатким - не сработало бы, если бы 0 было возможным значением делителя...

.
4
ответ дан 1 December 2019 в 20:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: