LINUX.ORG.RU

python update_wrapper

 ,


0

3

что неправильно в коде? почему test().__doc__ == None?

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from functools import update_wrapper


def setupmethod(wrapped):
    def wrapper(*args, **kwargs):
        return wrapped(*args, **kwargs)
    return update_wrapper(wrapper, wrapped)


@setupmethod
def testwrap(f):
    return f


@testwrap
def test():
    """Closes the database again at the end of the request."""
    print('test')

print(test().__doc__)

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

Function.prototype.docstring=function(){
 return (this+"").match(/\/\*([^*]*)\*\//)[1]
}

f=function(){
  /*docs here*/
  blablabla
}

console.log(f.docstring()) // docs here

tysonfury2015
()
Ответ на: комментарий от tysonfury2015

В JS, кстати, еще проще можно сделать. Ф-ция — это объект, соответственно, к любой функции можно просто прицепить свойство, например, __doc__

tysonfury2015
()
Ответ на: комментарий от tysonfury2015

преподноситься как фича

Никогда не видел чтобы это как-то особо преподносилось.

true_admin ★★★★★
()
Ответ на: комментарий от tysonfury2015

Ф-ция — это объект, соответственно, к любой функции можно просто прицепить свойство, например, __doc__

У тебя какой-то пунктик про питон что-ли? В нём тоже так можно.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

У тебя какой-то пунктик про питон что-ли?

Да, я считаю, что это профанация Ъ-ООП:) Чем больше людей уйдет с питона, тем больше придут в нормальные ООП языки.

В нём тоже так можно.

Ну, а зачем тогда этот онанизм? «„„„„“

tysonfury2015
()
Ответ на: комментарий от tysonfury2015

Чем больше людей уйдет с питона, тем больше придут в нормальные ООП языки.

Это ты сейчас js назвал нормальным?

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Ну, по крайней мере, в основе своей, он более-менее нормальный. Сейчас туда тоже вывалили кучу поноса, но этот синтаксический мусор можно просто игнорировать. Безусловно, JS, на порядок мощней питона, как ООП-язык.

tysonfury2015
()
Ответ на: комментарий от true_admin

Я уверен в этом. JS произошел от Self — потомка смоллтока. Он унаследовал мощь Self, пусть и не на 100%. А ООП питона — это жабское ООП.

tysonfury2015
()
Ответ на: комментарий от true_admin

Безусловно. Например, ты можешь иметь произвольное количество суперклассов, и манипулировать при помощи этих суперклассов объектами в рантайме, это метаобъектный протокол, в чистейшем, незамутненном виде.

tysonfury2015
()
Ответ на: комментарий от tysonfury2015

Чем больше людей уйдет с питона

Я за любой кипишь кроме голодовки, братюнь
У меня есть парсер логов приложения, ~300 строк на питоне
Ну ты понял.
Слушаю твои предложения и сказочные перспективы

zolden ★★★★★
()
Последнее исправление: zolden (всего исправлений: 1)
Ответ на: комментарий от zolden

Лучше поздно, чем никогда. Помимо всего прочего, скорость JS растет как на дрожжах, чего о питоне не скажешь. Плюс, проблемы с совместимостью.

tysonfury2015
()
Ответ на: комментарий от true_admin

Object.prototype.create=function(){return Object.create(this)}


Writer={
  writeFoo: function(){console.log(this.foo+this.__proto__.foo)},
  writeBar: function(){console.log(this.bar+this.__proto__.bar)},
  write: function(){this[this.rule]()},
  foo: "foo",
  bar: "bar"
}

Writer_son=Writer.create()
Writer_son.rule="writeFoo"

writer1=Writer_son.create()
writer2=Writer_son.create()

writer1.rule="writeBar"

writer1.write()
writer2.write()

Writer_son.bar="fuck"

writer1.write()
writer2.write()

//out:
barbar
foofoo
fuckfuck
foofoo

tysonfury2015
()
Ответ на: комментарий от tysonfury2015

Это ужасно, не дай бог такое в продакшене увидеть. И, наконец, конкретно этот пример вообще не требует того что ты сказал. Замени «this.foo+this.__proto__.foo» на «this.foo+this.foo» и вывод останется таким же. Что значит что данный код легко перекладывается на питон.

Object.prototype, по-моему, трогать не рекомендуется вообще. Но тут тебе виднее, я js вообще не владею.

Ну и в большинстве кода извраты с ООП вообще не нужны. Чем проще программа тем лучше. Поэтому бессмысленно уходить с питона только потому что там нет прототипов из коробки. Наконец, если они так нужны то ты можешь добавить их сам: http://tobyho.com/2009/05/23/prototype-inheritence-in/

Верно и другое: js точно так же можно «проапгрейдить» до питона. Но, повторюсь, это не та фишка за которой надо гнаться.

true_admin ★★★★★
()
Последнее исправление: true_admin (всего исправлений: 1)
-print(test().__doc__)
+print(test.__doc__)

__doc__ это же свойство объекта функции, а не её результата, не надо её вызывать для обращения к свойству.

xaizek ★★★★★
()
Ответ на: комментарий от true_admin

ты сказал. Замени «this.foo+this.__proto__.foo» на «this.foo+this.foo» и вывод останется таким же. Что значит что данный код легко перекладывается на питон.

не, объект тоже может иметь свой собственный foo.

В питоне основная проблема в том, что функции не могут динамически биндится. Там this всегда указывает на объект, в котором он определен. Поэтому, например, ф-ция, определенная в суперклассе, не увидит переменную, которая определена в подклассе(если она наследуется делегированием).

Иными словами, ф-ция может жить отделной от объекта жизнью.

;(function(){return this.a}).call(someObject)

Object.prototype, по-моему, трогать не рекомендуется вообще

можно создать класс — экземпляр Object, и вносить изменения в него, а потом от него наследовать. Будет то же самое, я просто не стал усложнять.

Чем проще программа тем лучше

Я с этим согласен, но в сложных случаях гибкость языка помогает бороться со сложностью.

tysonfury2015
()
Ответ на: комментарий от tysonfury2015

Поэтому, например, ф-ция, определенная в суперклассе, не увидит переменную, которая определена в подклассе(если она наследуется делегированием)

Не уверен что тебя понял, но вот этот код работает:

class Parent:
  def say_b(self):
    print(self.b)

class Child(Parent):
  b = "surprise"

if __name__ == '__main__':
  obj = Child()
  obj.say_b()

// выхлоп
$ ./test.py 
surprise

В питоне тоже функция может жить отдельной жизню. Ты можешь методу подсунуть любой self какой захочешь: конструкция obj.say_b() эквивалентна type(obj).say_b(obj) .

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

По приведенному коду трудо что-то понять. Непонятно, наследуется ли say_b делегированием, или она заново создается при инициализации child, и биндиться к нему. Пусть b будет находится не в классе, а в экземпляре, и перепиши вот так:

Object.prototype.create=function(){return Object.create(this)}


Parent={
  say_b: function(){console.log(this.b)}
}

Child=Parent.create()


obj=Child.create()
obj.b="suprise"

Parent.say_b=function(){console.log(this.b+"foo")}

obj.say_b()

//out: suprisefoo

Будет ясней, я думаю. Если работает также, значит, скорей всего, я ошибся.

tysonfury2015
()
Ответ на: комментарий от tysonfury2015

Спасибо, к вам вопросов больше нет

zolden ★★★★★
()
Ответ на: комментарий от tysonfury2015

Я немного запутался в терминологии, поэтому просто расскажу как работает питон. Допустим, есть код «a.b». По-дефолту, сначала будет поиск аттрибута «b» в объекте «a» (который суть просто словарь). Если не нашлось то ищем в иерархии классов.

Так же есть «волшебные» методы которые позволяют полностью перехватить и кастомизировать доступ к полям. Поэтому на питоне, я думаю, можно достаточно точно сэмулировать поведение js (если это надо). Есть ещё особая чёрная магия «метаклассы», но не будем об этом.

А на js можно, например, перехватить доступ к несуществующим полям?

PS код который, кмк, эквивалентен твоему:

class Parent:
  def say_b(self):
    print(self.b)

class Child(Parent):
  pass

obj = Child()
obj.b = "surprise"

Parent.say_b = lambda self: print(self.b+"foo")

obj.say_b()

// output
surprisefoo
true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Да, то как ты рассказываешь, похоже на то, что и в JS. Возможно я ошибался во многом.

А на js можно, например, перехватить доступ к несуществующим полям?

Да, есть объект Proxy

tysonfury2015
()
Ответ на: комментарий от true_admin

правда, мне не особо нравится такая реализация proxy как в JS. Там, есть косяки, код с ними не особо ясный. К тому-же, они пока не везде поддерживаются, емнип. В Io, например, сделано очень просто. В любом объекте, просто определяешь метод forward, и все. Даное поведение автоматом унаследуют все дети. В JS так нельзя, объект должен быть экземпляром Proxy, чтобы реализовать это. И есть там еще подводные камни. Короче, эта фича кривовата реализована в JS, врать не буду.

tysonfury2015
()
Ответ на: комментарий от true_admin

Есть ещё особая чёрная магия «метаклассы»,

Прочитал про метаклассы, в этом, как раз, с точки зрения JS, никакой магии нет. В JS все по-дефолту так и работает. Любой класс является объектом. В JS вообще любой произвольно взятый объект можно сделать классом, безо всяких деклараций. В этом отношении он превосходит даже смоллток и руби (как и любой прототипный ЯП), все концептуально проще.

tysonfury2015
()
Ответ на: комментарий от tysonfury2015

Да, то как ты рассказываешь, похоже на то, что и в JS. Возможно я ошибался во многом.

Опять облажался, эксперт? Ну, ничего, бывает, особенно с некоторыми :)

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

o={ a: 1, f: function(){console.log(this.a)} } o1={ a: 10, f: o.f } o1.f()// 10 Это, типа непредсказуемое поведение this, и дальше выводы, что js — говно, и в питоне, дескать, не так. Но если в питоне все не так (а именно — this связывается динамически с текущим контекстом вызова), то непонятно, как это может работать как описал true_admin. Что-то тут не чисто, все равно.

anonymous
()
Ответ на: комментарий от anonymous

Выучи уже питон. Он не так динамичен, как твоя любимая наркота, которой ты любишь обмазываться, поэтому на нем стараются писать что-нить полезное, а не надрачивать на его мощщу. Заодно и сравнишь объективно (надеюсь).

А тебя уже забанили? Красава.

Virtuos86 ★★★★★
()
Ответ на: комментарий от anonymous

this связывается динамически с текущим контекстом вызова

В питоне есть два «класса» методов: bound и unbound. Когда ты оперируешь над методами инстанса (объекта) то у тебя bound-версия (т.е. магически подставляется self; можно о нём думать как о замыкании). Когда ты обращаешься к полям класса то у тебя методы unbound (т.е. никакого self нет, его надо передавать явно).

Именно поэтому self резолвится так как он резолвится. Никакой магии нету.

true_admin ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.