بالموضع أو بالاسم
يمكن تمرير الوسائط بالموضع (تُطابق المعاملات بالترتيب) أو بالاسم (quantity=200). تجعل الأسماء الاستدعاء مقروءًا عندما يكون للدالة عدة مدخلات من النوع نفسه، وتتيح تمرير الوسائط بأي ترتيب. يجب أن تأتي الوسائط الموضعية أولًا؛ وبعد أن تستخدم اسمًا يجب أن تكون البقية مسمّاة أيضًا.
def pnl(entry, exit_price, quantity):
return (exit_price - entry) * quantity
print(pnl(184.0, 185.5, 200)) # 300.0
print(pnl(quantity=200, entry=184.0, exit_price=185.5)) # 300.0القيم الافتراضية تجعل المعاملات اختيارية
اكتب name=value في سطر def فيستطيع المستدعي حذف هذه الوسيطة وتُستخدم القيمة الافتراضية. تأتي المعاملات ذات القيم الافتراضية بعد التي بلا قيم. تناسب القيم الافتراضية الإعدادات المتشابهة غالبًا مثل نسبة عمولة أو حد أدنى، ويمكن استبدال أي منها بالاسم.
# Parameters with a default are optional
def fee(notional, rate=0.001, minimum=1.0):
return max(minimum, notional * rate)
print(fee(36850.0)) # 36.85
print(fee(36850.0, rate=0.0005)) # 18.425
print(fee(100.0, minimum=0.5)) # 0.5أي عدد من الوسائط: *args
يجمع المعامل المكتوب *prices كل الوسائط الموضعية الإضافية في صف (tuple)، فتعمل average(1, 2, 3) وaverage(1, 2, 3, 4, 5) كلتاهما. والعكس يحدث عند الاستدعاء: average(*quotes) تفكّ قائمة إلى وسائط منفصلة.
# *prices collects the extra arguments into a tuple
def average(*prices):
return sum(prices) / len(prices)
print(average(184.0, 185.0, 186.0)) # 185.0
quotes = [184.0, 185.0]
print(average(*quotes)) # 184.5أي خيارات مسمّاة: **options
وبالطريقة نفسها يجمع **options الوسائط المسمّاة الإضافية في قاموس من الأسماء والقيم (سيكون للقواميس موضوعها الخاص قريبًا). وهو يناسب الدوال التي تقبل إضافات اختيارية مثل إعدادات أمر. تعطي sorted(options) الأسماء بترتيب أبجدي فيصبح الناتج متوقعًا.
# **options collects extra named arguments into a dictionary
def describe(symbol, **options):
text = symbol
for name in sorted(options):
text += f" {name}={options[name]}"
return text
print(describe("AAPL", tif="day", limit=184.5)) # AAPL limit=184.5 tif=dayفخ القيمة الافتراضية القابلة للتعديل
تُنشأ القيمة الافتراضية مرة واحدة عند تعريف الدالة لا عند كل استدعاء. ومع عدد أو نص لا ضرر في ذلك. أما مع قائمة فإن كل استدعاء يستخدم القيمة الافتراضية يتشارك القائمة نفسها ويغيّرها. الحل المعتاد أن تكون القيمة الافتراضية None وتُنشأ قائمة جديدة داخل الدالة.
# A default list is created once and shared by every call
def add_fill(fill, fills=[]):
fills.append(fill)
return fills
print(add_fill(100)) # [100]
print(add_fill(200)) # [100, 200] <- surprise: the same list
# The fix: default to None and build a new list inside
def add_fill_fixed(fill, fills=None):
if fills is None:
fills = []
fills.append(fill)
return fills
print(add_fill_fixed(100)) # [100]
print(add_fill_fixed(200)) # [200]- استخدم الأسماء في الاستدعاءات ذات المدخلات المتعددة من النوع نفسه.
- قيم افتراضية للإعدادات المتشابهة غالبًا؛ وليس قائمة أو قاموسًا أبدًا.
*argsلأي عدد من القيم، و**optionsللإضافات المسمّاة.
التالي: النطاق والإغلاقات لنرى الأسماء التي تراها الدالة وكيف تتذكر القيم.
المختبر: ما الذي يُقيَّم
- اجعل الكمية والاتجاه اختياريين باستخدام
position_pnl25 نقطة - اقبل أي عدد من الأسعار باستخدام
average25 نقطة - اقبل خيارات الأمر المسمّاة باستخدام
describe_order25 نقطة - تجنّب فخ القائمة المشتركة باستخدام
add_fill25 نقطة