السلام عليكم ورحمة الله
ارى في كثير من التطبيقات والدروس وخصوصا مع الدوال العبارة التالية :
*args and **kwarg
فماذا تعني ارجو التوضيح مع مثال لاني بحثت كثيرا لكن لم استوعبها
السلام عليكم ورحمة الله
ارى في كثير من التطبيقات والدروس وخصوصا مع الدوال العبارة التالية :
*args and **kwarg
فماذا تعني ارجو التوضيح مع مثال لاني بحثت كثيرا لكن لم استوعبها
حسنا ، لنشرحها بالتدريج
args
بداية
>>> def sum_elements(listofelements): ... print "listofelements=", str(listofelements) ... sum = 0 ... for el in listofelements: ... sum += el ... return sum ... >>> sum_elements([1,2,3,4,5]) listofelements= [1, 2, 3, 4, 5] 15
الكود يعمل بصورة رائعة ، ولكن ظهرت لنا مشكلة وهي
أنني لاأريد أن أستدعي الدالة sum_elements بهذا الشكل
sum_elements([1,2,3,4,5])
ولكن بهذا الشكل
>>> sum_elements(1,2,3,4,5) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: sum_elements() takes exactly 1 argument (5 given)
فالخطأ الناتج أن هذه الدالة تأخذ معامل واحد وليس 5 معاملات!
فربما تريد أن تعيد تعريفها كالتالي
def sum_elements(a,b,c,d,e):return a+b+c+d+e
الآن كيف أخبر sum_elements أن تجمع كل المعاملات -ربما لاأريد أن أمرر 5 معاملات ربما فقط 4 أو ربما 2 او ربما 10- التي ستمرر لها ؟
الحل: فلنذهب إلى *args وهي تعبر عن المعاملات الممررة أيا كانت بإسم args
>>> def sum_elements2(*args): ... print "ARGS= ", args ... sum = 0 ... for el in args: ... sum += el ... return sum ...
>>> sum_elements2(1,2) ARGS= (1, 2) 3 >>> sum_elements2(1,2,3,4) ARGS= (1, 2, 3, 4) 10 >>> sum_elements2(1,2,3,4, 5, 6, 7, 8) ARGS= (1, 2, 3, 4, 5, 6, 7, 8) 36
طيب نقطة أخيرة ، إذا أردت أن أجمع عدد الأرقام من 0, 10 ولاأريد أن أكتب 10 معاملات ولدي الدالة range جاهزة تمدني ب list بها هذه الارقام
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> sum_elements2(range(10)) ARGS= ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9],) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 5, in sum_elements2 TypeError: unsupported operand type(s) for +=: 'int' and 'list'
سيظهر لي هذا الخطأ ، وذلك لأننا مررنا list بدل من عدد من العناصر ال integers
sum_elements2([0,1,2,3,4,5,6,7,8,9])
كيف نحل هذه المشكلة ؟ يجب أن توجد طريقة لنحول هذه ال list إلى مجموعة حرة من العناصر
بكل بساطة إستخدم المعامل * في بايثون لما يسمى ب unpack arguments (يسمى splat في بعض اللغات)
>>> sum_elements2(*range(10)) ARGS= (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) 45
ماذا عن **kwargs
حسنا، هي تسمى unpacking dictionary كما سمينا ال *args بإسم unpacking argument
def ls_options(showdirs=True, showsize=True, showperms=True, showversion=False, showlatime=False sort=False, showall=False):
if showdirs:
# dosomething
pass
if sort:
# dosomething to sort
pass
if showsize=:
# something to
passهل يعقل أن تكتب العشرات من المعاملات الإفتراضية في تعريف الدالة ؟
فالحل هو إستخدام شئ عام أنك ستشير لمعاملات إفتراضية عديدة عبر **kwargs
def ls_options2(**kwargs):
print "KWARGS: ", kwargs
if kwargs.has_key('showdirs'):
# dosomething
pass
if kwargs.has_key('sort'):
# dosomething to sort
pass
if kwargs.has_key('showsize'):
# something to
pass
ls_options2(showsize=True, showtime=True, showall=True, sort=False)
KWARGS: {'showsize': True, 'showtime': True, 'sort': False, 'showall': True}تم تعديل هذه المشاركة بواسطة ahmed_youssef في 16 مايو 2013 في 12:11
(map share people)
فضلا لاتقم بمراسلتي من أجل أسئلة لها أقسامها في المنتدى حتى تعم الفائدة على الجميع وللحصول على إجابات أفضل من أعضاء أكثر خبرة.
Weblog
@bitbucket
@xmonader
سلمت يداك شرح جميل والله ومفهوم
استاذنا الغالي شرح في غاية الروعة
اشكرك جزيل الشكر
الان فهمت
اسف لكني اعود لكم مره اخرى
مثلا هذا الكود للجانغو تلخبط علي انا كثيرا
class Comment(BaseModel):
author = CharField(max_length=60, blank=True)
body = TextField()
post = ForeignKey(Post, related_name="comments", blank=True, null=True)
created = DateTimeField(auto_now_add=True)
def __unicode__(self):
return u"%s: %s" % (self.post, self.body[:60])
def save(self, *args, **kwargs):
"""Email when a comment is added."""
if notify:
tpl = "Comment was was added to '%s' by '%s': \n\n%s"
message = tpl % (self.post, self.author, self.body)
from_addr = "no-reply@mydomain.com"
recipient_list = ["myemail@mydomain.com"]
send_mail("New comment added", message, from_addr, recipient_list)
super(Comment, self).save(*args, **kwargs)
لم افهم كيف تم استعمالها الان هذا موديول للتعليقات
بحيث عمليا تغييرت امور كثيره
وبالمناسبة ماهي الدالة super
وشكرا
تم تعديل هذه المشاركة بواسطة phpcraft في 17 مايو 2013 في 07:03
class Comment(BaseModel):
....
def save(self, *args, **kwargs):
"""Email when a comment is added."""
#do some extra stuff
....
#then call the parent.save method
super(Comment, self).save(*args, **kwargs)
هذا الصف يرث من BaseModel
ويريد التعديل فيما يحدث عندما تضغط Comment.save() فيريد ربما الإعلام بالبريد! -لايريد ال default behavior أو السلوك الإفتراضي عند تنفيذ دالة save-
فقام بإعادة تعريفها ليفعل فيها الأشياء الإضافية كإرسال إيميل للمستخدم بوجود تعليق جديد "ثم" إستدعى السلوك الإفتراضى من الأب BaseModel
super دالة تقوم بإعادة الأب ...
بالتوفيق
(map share people)
فضلا لاتقم بمراسلتي من أجل أسئلة لها أقسامها في المنتدى حتى تعم الفائدة على الجميع وللحصول على إجابات أفضل من أعضاء أكثر خبرة.
Weblog
@bitbucket
@xmonader
جزاك الله خيرا
ويجب علي ان اعود لدراسة الكلاسات
شكرا على النصيحة سابدا من الان بحثا عن كتاب او دروس للبدء من البداية وحتى النهاية ان شاء الله
هل تقصد هذا :)
نعم