টিএল; ডিআর : আপনি যদি পাইথন ৪.০ ব্যবহার করেন তবে এটি কেবল কাজ করে। আজকের (2019) হিসাবে 3.7+ আপনাকে ভবিষ্যতের বিবৃতি ( from __future__ import annotations
) ব্যবহার করতে হবে - পাইথন ৩.6 বা তার নীচে একটি স্ট্রিং ব্যবহার করুন।
আমার ধারণা আপনি এই ব্যতিক্রমটি পেয়েছেন:
NameError: name 'Position' is not defined
এটি কারণ Position
আপনি অজানা 4 ব্যবহার না করে আপনি কোনও টীকাটি ব্যবহার করার আগে এটি সংজ্ঞায়িত করতে হবে।
পাইথন ৩.7++: from __future__ import annotations
পাইথন 3.7 পিইপি 563 উপস্থাপন করেছে : টীকাগুলির স্থগিত মূল্যায়ন । ভবিষ্যতের বিবৃতি ব্যবহার করে এমন একটি মডিউল from __future__ import annotations
স্বয়ংক্রিয়ভাবে টীকাগুলি স্ট্রিং হিসাবে সংরক্ষণ করবে:
from __future__ import annotations
class Position:
def __add__(self, other: Position) -> Position:
...
এটি পাইথন ৪.০ এ ডিফল্ট হওয়ার কথা। পাইথন যেহেতু এখনও একটি গতিসম্পন্ন টাইপযুক্ত ভাষা তাই রানটাইমে কোনও প্রকারের চেকিং করা হয় না, টাইপিং টীকাগুলির কোনও কার্যকারিতা প্রভাবিত হওয়া উচিত, তাই না? ভুল! পাইথন ৩.7 এর আগে টাইপিং মডিউলটি মূলতম ধীরে ধীরে পাইথন মডিউলগুলির মধ্যে একটি হিসাবে ব্যবহৃত হত তাই আপনি যদি 3..7-এ উন্নীত হন তবে আপনি যদি পারফরম্যান্সে times গুণ বৃদ্ধি পেতে দেখবেন ।import typing
পাইথন <3.7: একটি স্ট্রিং ব্যবহার করুন
পিইপি 484 অনুসারে , আপনার নিজের ক্লাসের পরিবর্তে একটি স্ট্রিং ব্যবহার করা উচিত:
class Position:
...
def __add__(self, other: 'Position') -> 'Position':
...
আপনি যদি জ্যাঙ্গো কাঠামো ব্যবহার করেন তবে এটি পরিচিত হতে পারে কারণ জ্যাঙ্গো মডেলগুলি ফরোয়ার্ড রেফারেন্সগুলির জন্য স্ট্রিং ব্যবহার করে (বিদেশী মডেল যেখানে বিদেশী মডেল রয়েছে self
বা এখনও তা ঘোষিত হয়নি)। এটি পাইচার্ম এবং অন্যান্য সরঞ্জামগুলির সাথে কাজ করা উচিত।
সোর্স
আপনাকে ভ্রমণের হাতছাড়া করতে পিইপি 484 এবং পিইপি 563 এর প্রাসঙ্গিক অংশগুলি :
ফরোয়ার্ড রেফারেন্স
যখন কোনও প্রকার ইঙ্গিতটিতে এমন নাম থাকে যা এখনও সংজ্ঞায়িত হয়নি, তখন সেই সংজ্ঞাটি স্ট্রিং আক্ষরিক হিসাবে প্রকাশ করা হতে পারে, পরে সমাধান হতে পারে।
একটি পরিস্থিতি যেখানে এটি সাধারণত ঘটে থাকে তা একটি ধারক শ্রেণীর সংজ্ঞা, যেখানে শ্রেণিটি সংজ্ঞায়িত করা হয় কয়েকটি পদ্ধতির স্বাক্ষরে ঘটে। উদাহরণস্বরূপ, নিম্নলিখিত কোড (একটি সাধারণ বাইনারি ট্রি প্রয়োগের শুরু) কাজ করে না:
class Tree:
def __init__(self, left: Tree, right: Tree):
self.left = left
self.right = right
এর সমাধানের জন্য, আমরা লিখি:
class Tree:
def __init__(self, left: 'Tree', right: 'Tree'):
self.left = left
self.right = right
স্ট্রিং আক্ষরিক একটি বৈধ পাইথন এক্সপ্রেশন থাকা উচিত (যেমন, সংকলন (লিট, '', 'ইভাল') একটি বৈধ কোড অবজেক্ট হওয়া উচিত) এবং মডিউলটি সম্পূর্ণ লোড হয়ে গেলে এটি ত্রুটি ছাড়াই মূল্যায়ন করা উচিত। স্থানীয় এবং গ্লোবাল নেমস্পেস যেখানে এটি মূল্যায়ন করা হয় একই নামস্থান হওয়া উচিত যেখানে একই ফাংশনের ডিফল্ট আর্গুমেন্টগুলি মূল্যায়ন করা হত।
এবং পিইপি 563:
পাইথন ৪.০-তে, ফাংশন এবং পরিবর্তনশীল টীকাগুলি আর সংজ্ঞা সময়ে মূল্যায়ন করা হবে না। পরিবর্তে, একটি স্ট্রিং ফর্মটি সংশ্লিষ্ট __annotations__
অভিধানে সংরক্ষণ করা হবে । স্ট্যাটিক টাইপ চেকাররা আচরণের মধ্যে কোনও তফাত দেখতে পাবেন না, অন্যদিকে রানটাইম এ টীকাগুলি ব্যবহার করা সরঞ্জামগুলি স্থগিত মূল্যায়ন করতে হবে।
...
উপরে বর্ণিত কার্যকারিতাটি নীচের বিশেষ আমদানি ব্যবহার করে পাইথন ৩.7 থেকে শুরু করে সক্ষম করা যেতে পারে:
from __future__ import annotations
পরিবর্তে যে জিনিসগুলি আপনাকে প্রলোভন করতে পারে
উ: একটি ডামি সংজ্ঞা দিন Position
শ্রেণীর সংজ্ঞার আগে একটি ডামি সংজ্ঞা রাখুন:
class Position(object):
pass
class Position(object):
...
এটি এ থেকে মুক্তি পাবে NameError
এবং এমনকি ঠিক দেখাবে:
>>> Position.__add__.__annotations__
{'other': __main__.Position, 'return': __main__.Position}
তবে কি তাই?
>>> for k, v in Position.__add__.__annotations__.items():
... print(k, 'is Position:', v is Position)
return is Position: False
other is Position: False
বি। টীকা যুক্ত করার জন্য বানর-প্যাচ:
আপনি কিছু পাইথন মেটা প্রোগ্রামিং ম্যাজিক চেষ্টা করতে পারেন এবং টীকা যুক্ত করতে ক্লাসের সংজ্ঞাটি বানর-প্যাচে একটি ডেকরেটার লিখতে পারেন:
class Position:
...
def __add__(self, other):
return self.__class__(self.x + other.x, self.y + other.y)
সাজসজ্জার এর সমপরিমাণের জন্য দায়বদ্ধ হওয়া উচিত:
Position.__add__.__annotations__['return'] = Position
Position.__add__.__annotations__['other'] = Position
কমপক্ষে এটি সঠিক বলে মনে হচ্ছে:
>>> for k, v in Position.__add__.__annotations__.items():
... print(k, 'is Position:', v is Position)
return is Position: True
other is Position: True
সম্ভবত খুব বেশি ঝামেলা হয়েছে।
উপসংহার
আপনি যদি 3.6 বা নীচে ব্যবহার করছেন তবে ক্লাসের নাম সম্বলিত একটি স্ট্রিং আক্ষরিক ব্যবহার করুন, 3.7 ব্যবহার করে from __future__ import annotations
এবং এটি কেবল কাজ করবে।