2016-09-21 6 views
2

Я относительно новый ученик Python. Таким образом, при прохождении различных методов кодирования, я наткнулся на это:Использование параметров и подписи

from inspect import Parameter, Signature 

def make_signature(names): 
    return Signature(Parameter(name, Parameter.POSITIONAL_OR_KEYWORD) for name in names) 

class Structure: 
    list_fields = [] 
    def __init__(self, *args): 
     for name, val in zip(self.list_fields, args): 
      setattr(self, name, val) 

class Stock(Structure): 
    __signature__ = make_signature(['name', 'shares', 'price']) 
    #list_fields = ['name', 'shares', 'price'] 

class Point(Structure): 
    list_fields = ['x', 'y'] 

obj2=Point(20,40) 
obj1=Stock('googl', 100, 8000) 
print(obj1.name) 

Я понимаю Structure класса и его интеграции с Point классом, который наследует Structure класса, следовательно, это __init__ метода. Но когда я создаю объект класса Point, он не поддерживает Позиционные аргументы, но объект класса Stock поддерживает эту функцию.

  • Может ли кто-нибудь объяснить мне, почему & как это происходит?
  • Когда использовать параметр, Подпись?
  • Также как это связано с мета-программированием?
  • Еще несколько таких примеров.
  • что такое Parameter функция в make_signature способ и какой make_signature способ делает?
  • Поток программы i.e, какая функция возвращается кому и наоборот. Насколько мне известно, класс Stock и класс Point вызывают класс Structure, но когда он принимает метод make_signature?

И я попытался прочитать документацию о Signature, но эти примеры не являются такого рода и слишком много тяжелых вещей для меня, пока я заблудился возвратов этот код и я документации не мог найти хорошую объяснительную документация по мета-программированию на Python.

ответ

2

Может ли кто-нибудь объяснить мне, почему & как это происходит?

Оба класса только принимают позиционные аргументы, продиктованы *args в Structure.__init__:

s = Stock('pos_arg1', 'pos_arg2', 'pos_arg3') 
p = Point('pos_arg1', 'pos_arg2', 'pos_arg3') 

Разница заключается в том, что Stock фактически не установить какие-либо аргументы, потому что, так как вы закомментирована list_fields, Structure.__init__ будет использовать Structure.list_fields, который пуст. Вот почему попытка доступа к name на примере Stock вызывает AttributeError.

В обоих случаях list_fields какие аргументы могут быть установлены. Для экземпляра Point в предыдущем фрагменте x будет равен pos_arg1 и y будет равен pos_arg2; pos_arg3 существенно подбрасывается.Это связано с zip который строит кортежи, пока один из итерируемыми не исчерпывается:

for i, j in zip(['x', 'y'], ['pos_arg1', 'pos_arg2', 'pos_arg3']): 
    print(i, j) 

Печать:

x pos_arg1 
y pos_arg2 

Когда пустой список поставляется, не даже петли. Это то, что происходит, когда вы инициализации Stock, Structure.list_fields = [] используется:

for i, j in zip([], ['pos_arg1', 'pos_arg2', 'pos_arg3']): 
    print(i, j) 

Отпечатки ничего так не setattr s не собираются дозвонились.

Когда использовать параметр, Подпись?

Если вы хотите поддержать дальнейшее самоанализ ваших классов (или, вызываемых объектов в общем случае) можно добавить атрибут __signature__ к классу (как это делается с Stock) и получить его подобрал инструменты, такие как inspect.signature , то есть:

inspect.signature(Stock) 
Out[16]: <Signature (name, shares, price)> 

inspect.signature(Point) 
Out[17]: <Signature (*args)> 

Подпись пытается увидеть, если объект имеет object.__signature__ и если да создает представление подписи при вызове.

Кроме того, вы могли бы bind подписать себя и получить его для поддержки аргументов POSITIONAL_OR_KEYWORD.

В целом это будет представлять собой требование в очень немногих случаях. Короче: вы узнаете, если вам это понадобится.

Также как это связано с метапрограммой?

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

Еще несколько таких примеров.

Это слишком широкий запрос. Но ваш пример проистекает из презентации метапрограммирования Дэвида Беазли, here's the presentation.

Насколько мне известно, функция запаса и функция точки вызывает класс структуры, но где же применяется метод make_signature?

Оба Stock и Point использование Structure.__init__ который заполнит словарь экземпляра с атрибутами, определенными в list_fields.

__signature__ = make_signature([...]) выполняет , когда класс создается, Python выполняет тело class, когда он встречает его. make_signature будет вызван и создаст объект Signature, и будет выполнено задание __signature__.

+0

Не могли бы вы объяснить мне, что такое функция Parameter в методе make_signature и что делает метод make_signature? Можете ли вы также сказать мне поток программы, т.е. какая функция возвращается кому и наоборот. – BlackBeard

+0

Обновлен мой ответ @NiladriSekharBasu. Обратите внимание, что на ваш вопрос уже есть 5 вопросов в одном, вы не можете постоянно обновлять его, чтобы запрашивать дополнительную информацию; вот для чего нужны * новые * вопросы. –

Смежные вопросы