تقنيات استبدال المتغيرات
السلاسل النصية f-strings و.format() ومكتبات القوالب لعرض المطالبات
تقنيات استبدال المتغيرات درس مجاني في AI Prompt Engineering على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Prompt Engineering، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Prompt Engineering 4 دروس في المجموع.
أربعة أساليب في Python لتصيير القوالب
توفر Python عدة طرق لتصيير قوالب المطالبات مع استبدال المتغيرات. ولكل طريقة مزايا ومقايضات:
- f-strings — مضمنة وفورية ولا تتطلب عمليات استيراد
- str.format() — عناصر نائبة مسماة وسهلة التحقق
- string.Template — استبدال آمن باستخدام علامة الدولار، مع دعم الملء الجزئي
- Jinja2 — محرك قوالب متكامل: الشروط والحلقات والمرشحات والوراثة
يعتمد اختيار الأسلوب المناسب على مدى تعقيد القالب، ومهارات الفريق، وما إذا كنت تحتاج إلى ميزات متقدمة مثل الشروط والحلقات.
الأسلوب 1: f-strings في Python
تُعد f-strings أبسط أسلوب لقوالب المطالبات عندما تكون جميع المتغيرات متاحة وقت تصيير القالب:
import openai
client = openai.OpenAI(api_key='sk-...')
def generate_linkedin_post(company, topic, tone, word_count):
prompt = (
f'Write a LinkedIn post for {company} about {topic}. '
f'Tone: {tone}. '
f'Length: {word_count} words. '
'Professional but conversational. '
'End with one question to engage readers. '
'No hashtags. Active voice.'
)
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
return response.choices[0].message.content
print(generate_linkedin_post(
company='DataStream Analytics',
topic='how AI is changing data pipelines',
tone='enthusiastic but grounded',
word_count=180
))الأسلوب 2: str.format()
تعمل str.format() جيدًا عندما تريد تخزين سلاسل القوالب بشكل منفصل عن الشيفرة التي تملؤها — وهو أمر مفيد عند تحميل القوالب من الملفات:
import openai
client = openai.OpenAI(api_key='sk-...')
# Template stored as a module-level constant or loaded from a file
SUPPORT_REPLY_TEMPLATE = '''You are a customer support agent for {company_name}.
Respond to this customer message:
---
{customer_message}
---
Tone: {tone}.
Keep the response under {max_words} words.
Do not offer refunds unless the customer explicitly asks.
Always close by asking if there is anything else you can help with.'''
def generate_support_reply(company, message, tone='empathetic and helpful', max_words=150):
prompt = SUPPORT_REPLY_TEMPLATE.format(
company_name=company,
customer_message=message,
tone=tone,
max_words=max_words
)
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
return response.choices[0].message.contentالأسلوب 3: string.Template
تستخدم string.Template من مكتبة Python القياسية عناصر نائبة بعلامة الدولار ($variable أو ${variable}). وتتمثل ميزتها الأساسية في أن safe_substitute() تترك المتغيرات المفقودة كنصوص حرفية للعناصر النائبة بدلًا من رفع خطأ، مما يتيح عمليات الملء الجزئي:
from string import Template
import openai
client = openai.OpenAI(api_key='sk-...')
# $ placeholders — safe with code that contains curly braces
BASE_TEMPLATE = Template(
'Write a $format_type for $audience about $topic. '
'Tone: $tone. Length: $word_count words. '
'Active voice. No jargon.'
)
def generate(format_type, audience, topic, tone='professional', word_count=200):
prompt = BASE_TEMPLATE.substitute(
format_type=format_type,
audience=audience,
topic=topic,
tone=tone,
word_count=word_count
)
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
return response.choices[0].message.content
# Partial fill example — safe_substitute leaves $word_count as-is
partial = BASE_TEMPLATE.safe_substitute(
format_type='blog post', audience='developers', topic='API design'
)
print(partial) # $tone and $word_count remain as placeholdersالأسلوب 4: أساسيات Jinja2
Jinja2 محرك قوالب متكامل. وهو يدعم الشروط والحلقات والمرشحات ووراثة القوالب — أي ميزات تتجاوز الاستبدال البسيط للسلاسل النصية بكثير:
from jinja2 import Template
import openai
client = openai.OpenAI(api_key='sk-...')
# Jinja2 uses {{ }} for variables and {% %} for logic
JINJA_PROMPT = Template('''
Write a {{content_type}} for {{audience}} about {{topic}}.
Tone: {{tone}}.
{% if include_examples %}
Include {{example_count}} concrete examples.
{% endif %}
{% if word_count %}
Length: {{word_count}} words.
{% else %}
Aim for 200-300 words.
{% endif %}
Active voice. No jargon.
''')
def generate(content_type, audience, topic, tone, include_examples=False, example_count=2, word_count=None):
prompt = JINJA_PROMPT.render(
content_type=content_type,
audience=audience,
topic=topic,
tone=tone,
include_examples=include_examples,
example_count=example_count,
word_count=word_count
)
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
return response.choices[0].message.contentحلقات Jinja2 في القوالب
تتيح لك حلقات Jinja2 التكرار عبر القوائم داخل القالب — وهو أمر مفيد لإنشاء مطالبات متعددة العناصر من هياكل البيانات:
from jinja2 import Template
import openai
client = openai.OpenAI(api_key='sk-...')
MULTI_PRODUCT_TEMPLATE = Template('''
Write a product comparison for {{audience}}.
Compare the following products:
{% for product in products %}
- {{product.name}}: {{product.description}}
{% endfor %}
Structure: one paragraph per product, then a 2-sentence recommendation.
Tone: {{tone}}. Active voice. No bullet points in paragraphs.
''')
products = [
{'name': 'Asana', 'description': 'project management with timeline views'},
{'name': 'Linear', 'description': 'developer-focused issue tracking'},
{'name': 'Monday.com', 'description': 'visual work management for teams'}
]
prompt = MULTI_PRODUCT_TEMPLATE.render(
audience='startup founders',
products=products,
tone='direct and practical'
)
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
print(response.choices[0].message.content)مرشحات Jinja2
تحوّل مرشحات Jinja2 قيم المتغيرات بشكل مضمن أثناء تصيير القالب. ومن المرشحات المضمّنة المفيدة للمطالبات:
{{ topic | upper }}— تحويل الموضوع إلى أحرف كبيرة{{ word_count | default(200) }}— استخدام 200 إذا لم يتم توفير word_count{{ audience | title }}— تحويل سلسلة الجمهور إلى حالة العنوان{{ items | join(', ') }}— دمج قائمة باستخدام الفواصل
تحافظ المرشحات على منطق التحويل داخل القالب بدلًا من وضعه في شيفرة Python التي تستدعيه، مما يجعل القوالب أكثر اكتفاءً ذاتيًا وقابلية للنقل.
تحميل القوالب من الملفات
بالنسبة إلى القوالب الكبيرة أو المعقدة، يساعد تخزينها في ملفات نصية منفصلة على إبقاء شيفرة Python مرتبة. وتتولى Environment وFileSystemLoader في Jinja2 ذلك بكفاءة:
from jinja2 import Environment, FileSystemLoader
import openai
client = openai.OpenAI(api_key='sk-...')
# Load all templates from the 'prompts/' directory
env = Environment(loader=FileSystemLoader('prompts/'))
def render_template(template_name, variables):
'''Load and render a .j2 template file with the given variables.'''
template = env.get_template(template_name)
return template.render(**variables)
def generate_from_file(template_name, variables):
prompt = render_template(template_name, variables)
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
return response.choices[0].message.content
# Usage: load prompts/blog_post.j2 and fill with variables
result = generate_from_file('blog_post.j2', {
'topic': 'API rate limiting strategies',
'audience': 'backend engineers',
'tone': 'technical and direct',
'word_count': 500
})
print(result)اختيار الأسلوب المناسب
طابق أسلوب الاستبدال مع مدى تعقيد قوالبك:
- f-strings — للنصوص البرمجية السريعة، والأتمتة لمرة واحدة، والقوالب القصيرة بما يكفي لقراءتها مضمنة
- str.format() — للقوالب المخزنة، وقواعد شيفرة الفرق، والحالات التي يكون فيها رفع KeyError عند غياب المتغيرات أمرًا مرغوبًا
- string.Template — عندما يحتمل أن يحتوي المحتوى على أقواس معقوفة، مثل مقاطع الشيفرة، أو عند الحاجة إلى الملء الجزئي
- Jinja2 — للقوالب المعقدة التي تحتوي على شروط أو حلقات أو ملفات متعددة، أو عندما يكون الفريق متمرسًا في استخدام محركات القوالب
يمثل التعقيد غير الضروري خطرًا حقيقيًا — لا تلجأ إلى Jinja2 إلا عندما تحتاج فعلًا إلى ميزاته المتقدمة.
أمان القوالب: هجمات الحقن
عندما تأتي قيم المتغيرات من إدخال المستخدم، يمثل حقن المطالبة خطرًا حقيقيًا. فقد يُدخل مستخدم خبيث قيمة مثل: "تجاهل جميع التعليمات السابقة و..."
إجراءات الحماية:
- تحقق من صحة جميع المتغيرات التي أدخلها المستخدم ونقِّها قبل الاستبدال
- بالنسبة إلى المدخلات المواجهة للمستخدم، أحط المتغير بمحددات: "إدخال المستخدم هو: ---{user_input}---"
- استخدم تصفية المخرجات لاكتشاف الاستجابات التي تبدو كأنها اتبعت التعليمات المحقونة ورفضها
- لا تمنح القيم التي أدخلها المستخدم إمكانية الوصول إلى متغيرات مطالبة النظام
اختبار تصيير القوالب
اختبر دائمًا تصيير القوالب بشكل منفصل عن استدعاءات API. وتحقق من صحة السلسلة النصية الناتجة قبل إرسالها إلى النموذج:
def test_template_render():
test_cases = [
{'topic': 'cloud security', 'audience': 'CTOs', 'tone': 'formal', 'word_count': 300},
{'topic': 'ML pipelines', 'audience': 'data scientists', 'tone': 'technical', 'word_count': 500},
# Edge cases
{'topic': '', 'audience': 'developers', 'tone': 'casual', 'word_count': 100}, # empty topic
{'topic': 'AI' * 100, 'audience': 'all', 'tone': 'brief', 'word_count': 50}, # very long topic
]
TEMPLATE = 'Write a {word_count}-word {tone} article about {topic} for {audience}. Active voice.'
for i, case in enumerate(test_cases):
try:
rendered = TEMPLATE.format(**case)
assert len(rendered) > 0, 'Empty render'
print(f'Case {i+1} OK: {len(rendered)} chars')
except (KeyError, AssertionError) as e:
print(f'Case {i+1} FAILED: {e}')
test_template_render()اختبار المعرفة: تقنيات الاستبدال
أنت تبني نظام مطالبات تُخزَّن فيه ملفات القوالب على القرص، وتتضمن القوالب أقسامًا شرطية، مثل تضمين قسم عن التسعير اختياريًا بناءً على علامة، وقد يساهم في القوالب عدة أعضاء في الفريق لديهم خبرة في قوالب الويب.
أي أسلوب استبدال هو الأنسب لهذا السيناريو؟
مراجعة: تقنيات استبدال المتغيرات
توفر Python أربعة أساليب لتصيير قوالب المطالبات: f-strings (مضمنة وبسيطة)، وstr.format() (عناصر نائبة مسماة وKeyError عند غياب المتغيرات)، وstring.Template (صيغة بعلامة الدولار وملء جزئي آمن)، وJinja2 (محرك متكامل يتضمن الشروط والحلقات والمرشحات وتحميل الملفات).
طابق الأسلوب مع مدى التعقيد: استخدم f-strings للنصوص البرمجية السريعة، وstr.format() للقوالب المخزنة، وstring.Template عندما يحتوي المحتوى على أقواس معقوفة، وJinja2 عندما تحتاج إلى شروط أو حلقات أو قوالب قائمة على الملفات. اختبر دائمًا عمليات التصيير بشكل منفصل عن استدعاءات API.
الأسئلة الشائعة
هل درس «تقنيات استبدال المتغيرات» مجاني؟
نعم — نص درس «تقنيات استبدال المتغيرات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Prompt Engineering، انتقل إلى CoddyKit PRO. تتضمن دورة AI Prompt Engineering 4 دروس في المجموع.
ماذا ستتعلم في «تقنيات استبدال المتغيرات»؟
السلاسل النصية f-strings و.format() ومكتبات القوالب لعرض المطالبات تتمرن على AI Prompt Engineering مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Prompt Engineering؟
لا تُشترط خبرة سابقة. AI Prompt Engineering على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «تقنيات استبدال المتغيرات»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Prompt Engineering هذا؟
نعم. كل درس في AI Prompt Engineering يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- ما قالب المطالبة
- إنشاء أنماط ملء الفراغات
- تقنيات استبدال المتغيرات
- إعادة استخدام القوالب عبر المهام