পাইথন এর টাইপ্স পরিচিতি¶
Python-এ ঐচ্ছিক "টাইপ হিন্ট" (যা "টাইপ অ্যানোটেশন" নামেও পরিচিত) এর জন্য সাপোর্ট রয়েছে।
এই "টাইপ হিন্ট" বা অ্যানোটেশনগুলি এক ধরণের বিশেষ সিনট্যাক্স যা একটি ভেরিয়েবলের টাইপ ঘোষণা করতে দেয়।
ভেরিয়েবলগুলির জন্য টাইপ ঘোষণা করলে, এডিটর এবং টুলগুলি আপনাকে আরও ভালো সাপোর্ট দিতে পারে।
এটি পাইথন টাইপ হিন্ট সম্পর্কে একটি দ্রুত টিউটোরিয়াল / রিফ্রেশার মাত্র। এটি FastAPI এর সাথে ব্যবহার করার জন্য শুধুমাত্র ন্যূনতম প্রয়োজনীয়তা কভার করে... যা আসলে খুব একটা বেশি না।
FastAPI এই টাইপ হিন্টগুলির উপর ভিত্তি করে নির্মিত, যা এটিকে অনেক সুবিধা এবং লাভ প্রদান করে।
তবে, আপনি যদি কখনো FastAPI ব্যবহার নাও করেন, তবুও এগুলি সম্পর্কে একটু শেখা আপনার উপকারে আসবে।
Note
যদি আপনি একজন Python বিশেষজ্ঞ হন, এবং টাইপ হিন্ট সম্পর্কে সবকিছু জানেন, তাহলে পরবর্তী অধ্যায়ে চলে যান।
প্রেরণা¶
চলুন একটি সাধারণ উদাহরণ দিয়ে শুরু করি:
def get_full_name(first_name, last_name):
full_name = first_name.title() + " " + last_name.title()
return full_name
print(get_full_name("john", "doe"))
এই প্রোগ্রামটি কল করলে আউটপুট হয়:
John Doe
ফাংশনটি নিম্নলিখিত কাজ করে:
first_name
এবংlast_name
নেয়।- প্রতিটির প্রথম অক্ষরকে
title()
ব্যবহার করে বড় হাতের অক্ষরে রূপান্তর করে। - তাদেরকে মাঝখানে একটি স্পেস দিয়ে concatenate করে।
def get_full_name(first_name, last_name):
full_name = first_name.title() + " " + last_name.title()
return full_name
print(get_full_name("john", "doe"))
এটি সম্পাদনা করুন¶
এটি একটি খুব সাধারণ প্রোগ্রাম।
কিন্তু এখন কল্পনা করুন যে আপনি এটি শুরু থেকে লিখছিলেন।
এক পর্যায়ে আপনি ফাংশনের সংজ্ঞা শুরু করেছিলেন, আপনার প্যারামিটারগুলি প্রস্তুত ছিল...
কিন্তু তারপর আপনাকে "সেই method কল করতে হবে যা প্রথম অক্ষরকে বড় হাতের অক্ষরে রূপান্তর করে"।
এটা কি upper
ছিল? নাকি uppercase
? first_uppercase
? capitalize
?
তারপর, আপনি পুরোনো প্রোগ্রামারের বন্ধু, এডিটর অটোকমপ্লিশনের সাহায্যে নেওয়ার চেষ্টা করেন।
আপনি ফাংশনের প্রথম প্যারামিটার first_name
টাইপ করেন, তারপর একটি ডট (.
) টাইপ করেন এবং Ctrl+Space
চাপেন অটোকমপ্লিশন ট্রিগার করার জন্য।
কিন্তু, দুর্ভাগ্যবশত, আপনি কিছুই উপযোগী পান না:
টাইপ যোগ করুন¶
আসুন আগের সংস্করণ থেকে একটি লাইন পরিবর্তন করি।
আমরা ঠিক এই অংশটি পরিবর্তন করব অর্থাৎ ফাংশনের প্যারামিটারগুলি, এইগুলি:
first_name, last_name
থেকে এইগুলি:
first_name: str, last_name: str
ব্যাস।
এগুলিই "টাইপ হিন্ট":
def get_full_name(first_name: str, last_name: str):
full_name = first_name.title() + " " + last_name.title()
return full_name
print(get_full_name("john", "doe"))
এটি ডিফল্ট ভ্যালু ঘোষণা করার মত নয় যেমন:
first_name="john", last_name="doe"
এটি একটি ভিন্ন জিনিস।
আমরা সমান (=
) নয়, কোলন (:
) ব্যবহার করছি।
এবং টাইপ হিন্ট যোগ করা সাধারণত তেমন কিছু পরিবর্তন করে না যা টাইপ হিন্ট ছাড়াই ঘটত।
কিন্তু এখন, কল্পনা করুন আপনি আবার সেই ফাংশন তৈরির মাঝখানে আছেন, কিন্তু টাইপ হিন্ট সহ।
একই পর্যায়ে, আপনি অটোকমপ্লিট ট্রিগার করতে Ctrl+Space
চাপেন এবং আপনি দেখতে পান:
এর সাথে, আপনি অপশনগুলি দেখে, স্ক্রল করতে পারেন, যতক্ষণ না আপনি এমন একটি অপশন খুঁজে পান যা কিছু মনে পরিয়ে দেয়:
আরও প্রেরণা¶
এই ফাংশনটি দেখুন, এটিতে ইতিমধ্যে টাইপ হিন্ট রয়েছে:
def get_name_with_age(name: str, age: int):
name_with_age = name + " is this old: " + age
return name_with_age
এডিটর ভেরিয়েবলগুলির টাইপ জানার কারণে, আপনি শুধুমাত্র অটোকমপ্লিশনই পান না, আপনি এরর চেকও পান:
এখন আপনি জানেন যে আপনাকে এটি ঠিক করতে হবে, age
-কে একটি স্ট্রিং হিসেবে রূপান্তর করতে str(age)
ব্যবহার করতে হবে:
def get_name_with_age(name: str, age: int):
name_with_age = name + " is this old: " + str(age)
return name_with_age
টাইপ ঘোষণা¶
আপনি এতক্ষন টাইপ হিন্ট ঘোষণা করার মূল স্থানটি দেখে ফেলেছেন-- ফাংশন প্যারামিটার হিসেবে।
সাধারণত এটি FastAPI এর ক্ষেত্রেও একই।
সিম্পল টাইপ¶
আপনি str
ছাড়াও সমস্ত স্ট্যান্ডার্ড পাইথন টাইপ ঘোষণা করতে পারেন।
উদাহরণস্বরূপ, আপনি এগুলো ব্যবহার করতে পারেন:
int
float
bool
bytes
def get_items(item_a: str, item_b: int, item_c: float, item_d: bool, item_e: bytes):
return item_a, item_b, item_c, item_d, item_d, item_e
টাইপ প্যারামিটার সহ জেনেরিক টাইপ¶
কিছু ডাটা স্ট্রাকচার অন্যান্য মান ধারণ করতে পারে, যেমন dict
, list
, set
এবং tuple
। এবং অভ্যন্তরীণ মানগুলোরও নিজেদের টাইপ থাকতে পারে।
এই ধরনের টাইপগুলিকে বলা হয় "জেনেরিক" টাইপ এবং এগুলিকে তাদের অভ্যন্তরীণ টাইপগুলি সহ ঘোষণা করা সম্ভব।
এই টাইপগুলি এবং অভ্যন্তরীণ টাইপগুলি ঘোষণা করতে, আপনি Python মডিউল typing
ব্যবহার করতে পারেন। এটি বিশেষভাবে এই টাইপ হিন্টগুলি সমর্থন করার জন্য রয়েছে।
Python এর নতুন সংস্করণ¶
typing
ব্যবহার করা সিনট্যাক্সটি Python 3.6 থেকে সর্বশেষ সংস্করণগুলি পর্যন্ত, অর্থাৎ Python 3.9, Python 3.10 ইত্যাদি সহ সকল সংস্করণের সাথে সামঞ্জস্যপূর্ণ।
Python যত এগিয়ে যাচ্ছে, নতুন সংস্করণগুলি এই টাইপ অ্যানোটেশনগুলির জন্য তত উন্নত সাপোর্ট নিয়ে আসছে এবং অনেক ক্ষেত্রে আপনাকে টাইপ অ্যানোটেশন ঘোষণা করতে typing
মডিউল ইম্পোর্ট এবং ব্যবহার করার প্রয়োজন হবে না।
যদি আপনি আপনার প্রজেক্টের জন্য Python-এর আরও সাম্প্রতিক সংস্করণ নির্বাচন করতে পারেন, তাহলে আপনি সেই অতিরিক্ত সরলতা থেকে সুবিধা নিতে পারবেন।
ডক্সে রয়েছে Python-এর প্রতিটি সংস্করণের সাথে সামঞ্জস্যপূর্ণ উদাহরণগুলি (যখন পার্থক্য আছে)।
উদাহরণস্বরূপ, "Python 3.6+" মানে এটি Python 3.6 বা তার উপরে সামঞ্জস্যপূর্ণ (যার মধ্যে 3.7, 3.8, 3.9, 3.10, ইত্যাদি অন্তর্ভুক্ত)। এবং "Python 3.9+" মানে এটি Python 3.9 বা তার উপরে সামঞ্জস্যপূর্ণ (যার মধ্যে 3.10, ইত্যাদি অন্তর্ভুক্ত)।
যদি আপনি Python-এর সর্বশেষ সংস্করণগুলি ব্যবহার করতে পারেন, তাহলে সর্বশেষ সংস্করণের জন্য উদাহরণগুলি ব্যবহার করুন, সেগুলি আপনাকে সর্বোত্তম এবং সহজতম সিনট্যাক্স প্রদান করবে, যেমন, "Python 3.10+"।
লিস্ট¶
উদাহরণস্বরূপ, একটি ভেরিয়েবলকে str
-এর একটি list
হিসেবে সংজ্ঞায়িত করা যাক।
ভেরিয়েবলটি ঘোষণা করুন, একই কোলন (:
) সিনট্যাক্স ব্যবহার করে।
টাইপ হিসেবে, list
ব্যবহার করুন।
যেহেতু লিস্ট এমন একটি টাইপ যা অভ্যন্তরীণ টাইপগুলি ধারণ করে, আপনি তাদের স্কোয়ার ব্রাকেটের ভিতরে ব্যবহার করুন:
def process_items(items: list[str]):
for item in items:
print(item)
typing
থেকে List
(বড় হাতের L
দিয়ে) ইমপোর্ট করুন:
from typing import List
def process_items(items: List[str]):
for item in items:
print(item)
ভেরিয়েবলটি ঘোষণা করুন, একই কোলন (:
) সিনট্যাক্স ব্যবহার করে।
টাইপ হিসেবে, typing
থেকে আপনার ইম্পোর্ট করা List
ব্যবহার করুন।
যেহেতু লিস্ট এমন একটি টাইপ যা অভ্যন্তরীণ টাইপগুলি ধারণ করে, আপনি তাদের স্কোয়ার ব্রাকেটের ভিতরে করুন:
from typing import List
def process_items(items: List[str]):
for item in items:
print(item)
Info
স্কোয়ার ব্রাকেট এর ভিতরে ব্যবহৃত এইসব অভন্তরীন টাইপগুলোকে "ইন্টারনাল টাইপ" বলে।
এই উদাহরণে, এটি হচ্ছে List
(অথবা পাইথন ৩.৯ বা তার উপরের সংস্করণের ক্ষেত্রে list
) এ পাস করা টাইপ প্যারামিটার।
এর অর্থ হচ্ছে: "ভেরিয়েবল items
একটি list
, এবং এই লিস্টের প্রতিটি আইটেম একটি str
।"
Tip
যদি আপনি Python 3.9 বা তার উপরে ব্যবহার করেন, আপনার typing
থেকে List
আমদানি করতে হবে না, আপনি সাধারণ list
ওই টাইপের পরিবর্তে ব্যবহার করতে পারেন।
এর মাধ্যমে, আপনার এডিটর লিস্ট থেকে আইটেম প্রসেস করার সময় সাপোর্ট প্রদান করতে পারবে:
টাইপগুলি ছাড়া, এটি করা প্রায় অসম্ভব।
লক্ষ্য করুন যে ভেরিয়েবল item
হল items
লিস্টের একটি এলিমেন্ট।
তবুও, এডিটর জানে যে এটি একটি str
, এবং তার জন্য সাপোর্ট প্রদান করে।
টাপল এবং সেট¶
আপনি tuple
এবং set
ঘোষণা করার জন্য একই প্রক্রিয়া অনুসরণ করবেন:
def process_items(items_t: tuple[int, int, str], items_s: set[bytes]):
return items_t, items_s
from typing import Set, Tuple
def process_items(items_t: Tuple[int, int, str], items_s: Set[bytes]):
return items_t, items_s
এর মানে হল:
- ভেরিয়েবল
items_t
হল একটিtuple
যা ৩টি আইটেম ধারণ করে, একটিint
, অন্য একটিint
, এবং একটিstr
। - ভেরিয়েবল
items_s
হল একটিset
, এবং এর প্রতিটি আইটেম হলbytes
টাইপের।
ডিক্ট¶
একটি dict
সংজ্ঞায়িত করতে, আপনি ২টি টাইপ প্যারামিটার কমা দ্বারা পৃথক করে দেবেন।
প্রথম টাইপ প্যারামিটারটি হল dict
-এর কীগুলির জন্য।
দ্বিতীয় টাইপ প্যারামিটারটি হল dict
-এর মানগুলির জন্য:
def process_items(prices: dict[str, float]):
for item_name, item_price in prices.items():
print(item_name)
print(item_price)
from typing import Dict
def process_items(prices: Dict[str, float]):
for item_name, item_price in prices.items():
print(item_name)
print(item_price)
এর মানে হল:
- ভেরিয়েবল
prices
হল একটিdict
:- এই
dict
-এর কীগুলি হলstr
টাইপের (ধরা যাক, প্রতিটি আইটেমের নাম)। - এই
dict
-এর মানগুলি হলfloat
টাইপের (ধরা যাক, প্রতিটি আইটেমের দাম)।
- এই
ইউনিয়ন¶
আপনি একটি ভেরিয়েবলকে এমনভাবে ঘোষণা করতে পারেন যেন তা একাধিক টাইপের হয়, উদাহরণস্বরূপ, একটি int
অথবা str
।
Python 3.6 এবং তার উপরের সংস্করণগুলিতে (Python 3.10 অন্তর্ভুক্ত) আপনি typing
থেকে Union
টাইপ ব্যবহার করতে পারেন এবং স্কোয়ার ব্র্যাকেটের মধ্যে গ্রহণযোগ্য টাইপগুলি রাখতে পারেন।
Python 3.10-এ একটি নতুন সিনট্যাক্স আছে যেখানে আপনি সম্ভাব্য টাইপগুলিকে একটি ভার্টিকাল বার (|
) দ্বারা পৃথক করতে পারেন।
def process_item(item: int | str):
print(item)
from typing import Union
def process_item(item: Union[int, str]):
print(item)
উভয় ক্ষেত্রেই এর মানে হল যে item
হতে পারে একটি int
অথবা str
।
সম্ভবত None
¶
আপনি এমনভাবে ঘোষণা করতে পারেন যে একটি মান হতে পারে এক টাইপের, যেমন str
, আবার এটি None
-ও হতে পারে।
Python 3.6 এবং তার উপরের সংস্করণগুলিতে (Python 3.10 অনতর্ভুক্ত) আপনি typing
মডিউল থেকে Optional
ইমপোর্ট করে এটি ঘোষণা এবং ব্যবহার করতে পারেন।
from typing import Optional
def say_hi(name: Optional[str] = None):
if name is not None:
print(f"Hey {name}!")
else:
print("Hello World")
Optional[str]
ব্যবহার করা মানে হল শুধু str
নয়, এটি হতে পারে None
-ও, যা আপনার এডিটরকে সেই ত্রুটিগুলি শনাক্ত করতে সাহায্য করবে যেখানে আপনি ধরে নিচ্ছেন যে একটি মান সবসময় str
হবে, অথচ এটি None
-ও হতে পারেও।
Optional[Something]
মূলত Union[Something, None]
-এর একটি শর্টকাট, এবং তারা সমতুল্য।
এর মানে হল, Python 3.10-এ, আপনি টাইপগুলির ইউনিয়ন ঘোষণা করতে Something | None
ব্যবহার করতে পারেন:
def say_hi(name: str | None = None):
if name is not None:
print(f"Hey {name}!")
else:
print("Hello World")
from typing import Optional
def say_hi(name: Optional[str] = None):
if name is not None:
print(f"Hey {name}!")
else:
print("Hello World")
from typing import Union
def say_hi(name: Union[str, None] = None):
if name is not None:
print(f"Hey {name}!")
else:
print("Hello World")
Union
বা Optional
ব্যবহার¶
যদি আপনি Python 3.10-এর নীচের সংস্করণ ব্যবহার করেন, তবে এখানে আমার খুবই ব্যক্তিগত দৃষ্টিভঙ্গি থেকে একটি টিপস:
- 🚨
Optional[SomeType]
ব্যবহার এড়িয়ে চলুন। - এর পরিবর্তে ✨
Union[SomeType, None]
ব্যবহার করুন ✨।
উভয়ই সমতুল্য এবং মূলে একই, কিন্তু আমি Union
-এর পক্ষে সুপারিশ করব কারণ "অপশনাল" শব্দটি মনে হতে পারে যে মানটি ঐচ্ছিক,অথচ এটি আসলে মানে "এটি হতে পারে None
", এমনকি যদি এটি ঐচ্ছিক না হয়েও আবশ্যিক হয়।
আমি মনে করি Union[SomeType, None]
এর অর্থ আরও স্পষ্টভাবে প্রকাশ করে।
এটি কেবল শব্দ এবং নামের ব্যাপার। কিন্তু সেই শব্দগুলি আপনি এবং আপনার সহকর্মীরা কোড সম্পর্কে কীভাবে চিন্তা করেন তা প্রভাবিত করতে পারে।
একটি উদাহরণ হিসেবে, এই ফাংশনটি নিন:
from typing import Optional
def say_hi(name: Optional[str]):
print(f"Hey {name}!")
🤓 Other versions and variants
def say_hi(name: str | None):
print(f"Hey {name}!")
name
প্যারামিটারটি Optional[str]
হিসেবে সংজ্ঞায়িত হয়েছে, কিন্তু এটি অপশনাল নয়, আপনি প্যারামিটার ছাড়া ফাংশনটি কল করতে পারবেন না:
say_hi() # ওহ না, এটি একটি ত্রুটি নিক্ষেপ করবে! 😱
name
প্যারামিটারটি এখনও আবশ্যিক (নন-অপশনাল) কারণ এটির কোনো ডিফল্ট মান নেই। তবুও, name
এর মান হিসেবে None
গ্রহণযোগ্য:
say_hi(name=None) # এটি কাজ করে, None বৈধ 🎉
সুখবর হল, একবার আপনি Python 3.10 ব্যবহার করা শুরু করলে, আপনাকে এগুলোর ব্যাপারে আর চিন্তা করতে হবে না, যেহুতু আপনি | ব্যবহার করেই ইউনিয়ন ঘোষণা করতে পারবেন:
def say_hi(name: str | None):
print(f"Hey {name}!")
🤓 Other versions and variants
from typing import Optional
def say_hi(name: Optional[str]):
print(f"Hey {name}!")
এবং তারপর আপনাকে নামগুলি যেমন Optional
এবং Union
নিয়ে আর চিন্তা করতে হবে না। 😎
জেনেরিক টাইপস¶
স্কোয়ার ব্র্যাকেটে টাইপ প্যারামিটার নেওয়া এই টাইপগুলিকে জেনেরিক টাইপ বা জেনেরিকস বলা হয়, যেমন:
আপনি সেই একই বিল্টইন টাইপ জেনেরিক্স হিসেবে ব্যবহার করতে পারবেন(ভিতরে টাইপ সহ স্কয়ারে ব্রাকেট দিয়ে):
list
tuple
set
dict
এবং Python 3.8 এর মতোই, typing
মডিউল থেকে:
Union
Optional
(Python 3.8 এর মতোই)- ...এবং অন্যান্য।
Python 3.10-এ, Union
এবং Optional
জেনেরিকস ব্যবহার করার বিকল্প হিসেবে, আপনি টাইপগুলির ইউনিয়ন ঘোষণা করতে ভার্টিকাল বার (|
) ব্যবহার করতে পারেন, যা ওদের থেকে অনেক ভালো এবং সহজ।
আপনি সেই একই বিল্টইন টাইপ জেনেরিক্স হিসেবে ব্যবহার করতে পারবেন(ভিতরে টাইপ সহ স্কয়ারে ব্রাকেট দিয়ে):
list
tuple
set
dict
এবং Python 3.8 এর মতোই, typing
মডিউল থেকে:
Union
Optional
- ...এবং অন্যান্য।
List
Tuple
Set
Dict
Union
Optional
- ...এবং অন্যান্য।
ক্লাস হিসেবে টাইপস¶
আপনি একটি ভেরিয়েবলের টাইপ হিসেবে একটি ক্লাস ঘোষণা করতে পারেন।
ধরুন আপনার কাছে Person
নামে একটি ক্লাস আছে, যার একটি নাম আছে:
class Person:
def __init__(self, name: str):
self.name = name
def get_person_name(one_person: Person):
return one_person.name
তারপর আপনি একটি ভেরিয়েবলকে Person
টাইপের হিসেবে ঘোষণা করতে পারেন:
class Person:
def __init__(self, name: str):
self.name = name
def get_person_name(one_person: Person):
return one_person.name
এবং তারপর, আবার, আপনি এডিটর সাপোর্ট পেয়ে যাবেন:
লক্ষ্য করুন যে এর মানে হল "one_person
হল ক্লাস Person
-এর একটি ইন্সট্যান্স।"
এর মানে এটি নয় যে "one_person
হল ক্লাস যাকে বলা হয় Person
।"
Pydantic মডেল¶
Pydantic হল একটি Python লাইব্রেরি যা ডাটা ভ্যালিডেশন সম্পাদন করে।
আপনি ডাটার "আকার" এট্রিবিউট সহ ক্লাস হিসেবে ঘোষণা করেন।
এবং প্রতিটি এট্রিবিউট এর একটি টাইপ থাকে।
তারপর আপনি যদি কিছু মান দিয়ে সেই ক্লাসের একটি ইন্সট্যান্স তৈরি করেন-- এটি মানগুলিকে ভ্যালিডেট করবে, প্রয়োজন অনুযায়ী তাদেরকে উপযুক্ত টাইপে রূপান্তর করবে এবং আপনাকে সমস্ত ডাটা সহ একটি অবজেক্ট প্রদান করবে।
এবং আপনি সেই ফলাফল অবজেক্টের সাথে এডিটর সাপোর্ট পাবেন।
অফিসিয়াল Pydantic ডক্স থেকে একটি উদাহরণ:
from datetime import datetime
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str = "John Doe"
signup_ts: datetime | None = None
friends: list[int] = []
external_data = {
"id": "123",
"signup_ts": "2017-06-01 12:22",
"friends": [1, "2", b"3"],
}
user = User(**external_data)
print(user)
# > User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3]
print(user.id)
# > 123
from datetime import datetime
from typing import Union
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str = "John Doe"
signup_ts: Union[datetime, None] = None
friends: list[int] = []
external_data = {
"id": "123",
"signup_ts": "2017-06-01 12:22",
"friends": [1, "2", b"3"],
}
user = User(**external_data)
print(user)
# > User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3]
print(user.id)
# > 123
from datetime import datetime
from typing import List, Union
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str = "John Doe"
signup_ts: Union[datetime, None] = None
friends: List[int] = []
external_data = {
"id": "123",
"signup_ts": "2017-06-01 12:22",
"friends": [1, "2", b"3"],
}
user = User(**external_data)
print(user)
# > User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3]
print(user.id)
# > 123
FastAPI মূলত Pydantic-এর উপর নির্মিত।
আপনি এই সমস্ত কিছুর অনেক বাস্তবসম্মত উদাহরণ পাবেন টিউটোরিয়াল - ইউজার গাইডে।
Tip
যখন আপনি Optional
বা Union[Something, None]
ব্যবহার করেন এবং কোনো ডিফল্ট মান না থাকে, Pydantic-এর একটি বিশেষ আচরণ রয়েছে, আপনি Pydantic ডকুমেন্টেশনে Required Optional fields সম্পর্কে আরও পড়তে পারেন।
মেটাডাটা অ্যানোটেশন সহ টাইপ হিন্টস¶
Python-এ এমন একটি ফিচার আছে যা Annotated
ব্যবহার করে এই টাইপ হিন্টগুলিতে অতিরিক্ত মেটাডাটা রাখতে দেয়।
Python 3.9-এ, Annotated
স্ট্যান্ডার্ড লাইব্রেরিতে অন্তর্ভুক্ত, তাই আপনি এটি typing
থেকে ইমপোর্ট করতে পারেন।
from typing import Annotated
def say_hello(name: Annotated[str, "this is just metadata"]) -> str:
return f"Hello {name}"
Python 3.9-এর নীচের সংস্করণগুলিতে, আপনি Annotated
-কে typing_extensions
থেকে ইমপোর্ট করেন।
এটি FastAPI এর সাথে ইতিমদ্ধে ইনস্টল হয়ে থাকবে।
from typing_extensions import Annotated
def say_hello(name: Annotated[str, "this is just metadata"]) -> str:
return f"Hello {name}"
Python নিজে এই Annotated
দিয়ে কিছুই করে না। এবং এডিটর এবং অন্যান্য টুলগুলির জন্য, টাইপটি এখনও str
।
কিন্তু আপনি এই Annotated
এর মধ্যকার জায়গাটির মধ্যে FastAPI-এ কীভাবে আপনার অ্যাপ্লিকেশন আচরণ করুক তা সম্পর্কে অতিরিক্ত মেটাডাটা প্রদান করার জন্য ব্যবহার করতে পারেন।
মনে রাখার গুরুত্বপূর্ণ বিষয় হল যে প্রথম টাইপ প্যারামিটার আপনি Annotated
-এ পাস করেন সেটি হল আসল টাইপ। বাকি শুধুমাত্র অন্যান্য টুলগুলির জন্য মেটাডাটা।
এখন আপনার কেবল জানা প্রয়োজন যে Annotated
বিদ্যমান, এবং এটি স্ট্যান্ডার্ড Python। 😎
পরবর্তীতে আপনি দেখবেন এটি কতটা শক্তিশালী হতে পারে।
Tip
এটি স্ট্যান্ডার্ড Python হওয়ার মানে হল আপনি আপনার এডিটরে, আপনি যে টুলগুলি কোড বিশ্লেষণ এবং রিফ্যাক্টর করার জন্য ব্যবহার করেন তাতে সেরা সম্ভাব্য ডেভেলপার এক্সপেরিয়েন্স পাবেন। ✨
এবং এছাড়াও আপনার কোড অন্যান্য অনেক Python টুল এবং লাইব্রেরিগুলির সাথে খুব সামঞ্জস্যপূর্ণ হবে। 🚀
FastAPI-এ টাইপ হিন্টস¶
FastAPI এই টাইপ হিন্টগুলি ব্যবহার করে বেশ কিছু জিনিস করে।
FastAPI-এ আপনি টাইপ হিন্টগুলি সহ প্যারামিটার ঘোষণা করেন এবং আপনি পান:
- এডিটর সাপোর্ট।
- টাইপচেক।
...এবং FastAPI একই ঘোষণাগুলি ব্যবহার করে:
- রিকুইরেমেন্টস সংজ্ঞায়িত করে: রিকোয়েস্ট পাথ প্যারামিটার, কুয়েরি প্যারামিটার, হেডার, বডি, ডিপেন্ডেন্সিস, ইত্যাদি থেকে।
- ডেটা রূপান্তর করে: রিকোয়েস্ট থেকে প্রয়োজনীয় টাইপে ডেটা।
- ডেটা যাচাই করে: প্রতিটি রিকোয়েস্ট থেকে আসা ডেটা:
- যখন ডেটা অবৈধ হয় তখন স্বয়ংক্রিয় ত্রুটি গ্রাহকের কাছে ফেরত পাঠানো।
- API ডকুমেন্টেশন তৈরি করে: OpenAPI ব্যবহার করে:
- যা স্বয়ংক্রিয় ইন্টার্যাক্টিভ ডকুমেন্টেশন ইউজার ইন্টারফেস দ্বারা ব্যবহৃত হয়।
এই সব কিছু আপনার কাছে অস্পষ্ট মনে হতে পারে। চিন্তা করবেন না। আপনি টিউটোরিয়াল - ইউজার গাইড এ এই সব কিছু প্র্যাকটিসে দেখতে পাবেন।
গুরুত্বপূর্ণ বিষয় হল, আপনি যদি স্ট্যান্ডার্ড Python টাইপগুলি ব্যবহার করেন, তবে আরও বেশি ক্লাস, ডেকোরেটর ইত্যাদি যোগ না করেই একই স্থানে FastAPI আপনার অনেক কাজ করে দিবে।
Info
যদি আপনি টিউটোরিয়ালের সমস্ত বিষয় পড়ে ফেলে থাকেন এবং টাইপ সম্পর্কে আরও জানতে চান, তবে একটি ভালো রিসোর্স হল mypy এর "cheat sheet"। এই "cheat sheet" এ আপনি Python টাইপ হিন্ট সম্পর্কে বেসিক থেকে উন্নত লেভেলের ধারণা পেতে পারেন, যা আপনার কোডে টাইপ সেফটি এবং স্পষ্টতা বাড়াতে সাহায্য করবে।