পাইথনের কোনও ক্লাসে উদাহরণস্বরূপ ভেরিয়েবলগুলি না হিসাবে ঘোষণা করা কি ভাল অভ্যাস?


68

নিম্নলিখিত শ্রেণীর বিবেচনা করুন:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

আমার সহকর্মীরা এটির মতো এটি সংজ্ঞায়িত করতে থাকে:

class Person:
    name = None
    age = None

    def __init__(self, name, age):
        self.name = name
        self.age = age

এর মূল কারণ হ'ল তাদের পছন্দের সম্পাদকটি স্বতঃপূরণের জন্য বৈশিষ্ট্যগুলি দেখায়।

ব্যক্তিগতভাবে, আমি দ্বিতীয়টিরটিকে অপছন্দ করি, কারণ এটি কোনও বোধগম্য নয় যে কোনও শ্রেণীর কাছে সেই বৈশিষ্ট্যগুলি সেট করা আছে None

কোনটি আরও ভাল অনুশীলন হবে এবং কী কারণে?


62
আপনার আইডিই কখনই কোন কোডটি লেখার নির্দেশ দেয় না?
মার্টিজন পিটারস

14
উপায় দ্বারা: একটি যথাযথ পাইথন আইডিই ব্যবহার করে (যেমন পাইচার্ম) __init__ইতিমধ্যে স্বতঃপূরণ ইত্যাদি সরবরাহ করে ইত্যাদি Noneবৈশিষ্ট্যগুলির জন্য আইডিই ব্যবহার করে আরও ভাল ধরণের আবিষ্কার করতে বাধা দেয়, সুতরাং পরিবর্তে বুদ্ধিমান ডিফল্ট ব্যবহার করা ভাল when সম্ভব).
বাকুরিউ

যদি এটি কেবল স্বাবলম্বনের জন্য হয় তবে আপনি টাইপ হিন্টিং ব্যবহার করতে পারেন এবং অতিরিক্ত ডকাস্ট্রিংগুলিও একটি প্লাস হবে।
দ্যাশি

3
একটি বিতর্কিত সমস্যা "আপনার আইডিই কখনই কোন কোডটি লিখবেন তা নির্দেশ করতে দেবেন না"। পাইথন ৩.6 অনুসারে ইন-লাইন টীকাগুলি এবং একটি typingমডিউল রয়েছে, যা আপনাকে আইডিই এবং লিন্টারে ইঙ্গিত সরবরাহ করতে দেয়, যদি এই ধরণের জিনিসটি আপনার অভিনব কল্পনা করে ...
সিজেড

1
ক্লাস স্তরে এই কার্যভারগুলি বাকি কোডগুলিতে কোনও প্রভাব ফেলবে না। তাদের কোনও প্রভাব নেই self। এমনকি যদি self.nameবা self.ageনির্ধারিত করা হয় নি __init__তারা উদাহরণস্বরূপ দেখা করবে না selfতারা কেবল ক্লাসে দেখা Person
jolvi

উত্তর:


70

আমি পরবর্তীকালের খারাপ অভ্যাসটিকে "" আপনি যা ভাবেন এটি করেন না "নিয়মের আওতায় আছি।

আপনার সহকর্মীর অবস্থানটি আবার লিখে দেওয়া যেতে পারে: "আমি ক্লাস-স্ট্যাটিক অর্ধ-বিশ্বব্যাপী ভেরিয়েবলগুলি তৈরি করতে যাচ্ছি যা কখনও অ্যাক্সেস করা যায় না, তবে যা __dict__আমার আইডিই করতে কেবল বিভিন্ন ক্লাসের নেমস্পেস টেবিলগুলিতে জায়গা নেয়" ) কিছু। "


4
ডটস্ট্রিংয়ের মতো কিছুটা ;-) অবশ্যই, পাইথনের একটি খুব সহজ পদ্ধতি রয়েছে যা তাদের প্রয়োজন, -OOযারা এটি প্রয়োজন তাদের জন্য p
স্টিভ জেসপ

15
স্থান গ্রহণ করা এই সম্মেলনের দুর্গন্ধের সবচেয়ে কম গুরুত্বপূর্ণ কারণ। এটি প্রতি এক ডজন বাইট (প্রক্রিয়া অনুসারে)। আমি মনে করি আমার সময় নষ্ট থাকার মত শুধু পড়া আপনার উত্তর এটা সংক্রান্ত অংশ, এটি স্থান খরচ কিভাবে গুরুত্বহীন নয়।

8
@ ডেলানান আমি এন্ট্রিগুলির অর্থহীন হওয়া সম্পর্কে মেমরির আকার সম্পর্কে একমত, আমি লজিক / মানসিক স্থান গ্রহণের চেয়ে বেশি চিন্তাভাবনা করি, আত্মবিজ্ঞানী ডিবাগিং করি এবং এর জন্য আরও পড়া এবং বাছাই করা প্রয়োজন, আমার ধারণা would আমি ~ এলএল
স্টারওয়েভার

3
প্রকৃতপক্ষে, আপনি যদি স্থান সম্পর্কে এই ভৌতিক হয়ে থাকেন তবে আপনি লক্ষ্য করবেন যে এটি স্থান বাঁচায় এবং সময় নষ্ট করে। অবিচ্ছিন্ন সদস্যরা শ্রেণি মানটি ব্যবহার করার জন্য পড়ে যান এবং অতএব কোনও কিছুইতে ম্যাপযুক্ত ভেরিয়েবলের কপিগুলির একগুচ্ছ নেই (প্রতিটি উদাহরণের জন্য একটি)। সুতরাং ব্যয়টি ক্লাসে কয়েকটি বাইট এবং সঞ্চয় প্রতি উদাহরণে কয়েকটি বাইট। তবে প্রতিটি ব্যর্থ চলক নাম অনুসন্ধানের জন্য অল্প সময়ের জন্য ব্যয় হয়।
জন জে ওবারমার্ক

2
আপনি যদি 8 টি বাইট নিয়ে চিন্তিত হন তবে আপনি পাইথনটি ব্যবহার করবেন না।
সিজেড

26

1. আপনার কোডটি বুঝতে সহজ করুন

কোড লিখিত চেয়ে অনেক বেশি বার পড়া হয়। আপনার কোড রক্ষণাবেক্ষণকারীটির কাজটিকে আরও সহজ করুন (এটি পরের বছর নিজেও হতে পারে)।

আমি কোনও কঠোর নিয়ম সম্পর্কে জানি না, তবে আমি ভবিষ্যতের কোনও উদাহরণ রাষ্ট্র পরিষ্কারভাবে ঘোষণা করার পছন্দ করি । একটি সঙ্গে ক্র্যাশ AttributeErrorযথেষ্ট খারাপ। উদাহরণস্বরূপ বৈশিষ্ট্যের জীবনকালটি স্পষ্টরূপে না দেখানো আরও খারাপ। সম্ভাব্য কল সিকোয়েন্সগুলি পুনরুদ্ধার করতে প্রয়োজনীয় মানসিক জিমন্যাস্টিকের পরিমাণ যা নির্ধারিত বৈশিষ্ট্যটিকে অনিবার্য করে তোলে তা সহজেই তুচ্ছ হতে পারে, ত্রুটির দিকে পরিচালিত করে।

সুতরাং আমি সাধারণত কনস্ট্রাক্টরের সমস্ত কিছুই সংজ্ঞায়িত করি না, তবে পরিবর্তনীয় বৈশিষ্ট্যের সংখ্যাও সর্বনিম্ন রাখার চেষ্টা করি।

২. শ্রেণী-স্তর এবং উদাহরণ স্তরের সদস্যদের মিশ্রিত করবেন না

classঘোষণার ডানদিকে আপনি যে কোনও কিছু সংজ্ঞায়িত করেন তা শ্রেণীর অন্তর্গত এবং শ্রেণীর সমস্ত দৃষ্টান্ত দ্বারা ভাগ করা হয়। যেমন আপনি যখন ক্লাসের ভিতরে কোনও ফাংশন সংজ্ঞায়িত করেন, এটি একটি পদ্ধতিতে পরিণত হয় যা সমস্ত দৃষ্টান্তের জন্য একই same একই তথ্য সদস্যদের জন্য প্রযোজ্য। এটি সম্পূর্ণরূপে উদাহরণস্বরূপ বৈশিষ্ট্যগুলির বিপরীত যা আপনি সাধারণত সংজ্ঞায়িত করেন __init__

শ্রেণি-স্তরের ডেটা সদস্যরা স্থির হিসাবে সবচেয়ে কার্যকর:

class Missile(object):
  MAX_SPEED = 100  # all missiles accelerate up to this speed
  ACCELERATION = 5  # rate of acceleration per game frame

  def move(self):
    self.speed += self.ACCELERATION
    if self.speed > self.MAX_SPEED:
      self.speed = self.MAX_SPEED
    # ...

2
হ্যাঁ, তবে শ্রেণিকেন্দ্র এবং উদাহরণ-স্তরের সদস্যদের মিশ্রণ ডিএফ যা করায় তা অনেক বেশি । এটি এমন ফাংশন তৈরি করে যা আমরা বস্তুর বৈশিষ্ট্য হিসাবে বিবেচনা করি তবে সত্যই শ্রেণীর সদস্য। একই জিনিস সম্পত্তি এবং এর অসুস্থতার জন্য যায় । শ্রেণি দ্বারা সত্যই মধ্যস্থতা করা হয় যখন কাজ বস্তুর অন্তর্গত যে মায়া দেওয়া যে বাদাম না যাওয়ার একটি সময়-সম্মানজনক উপায়। পাইথনের নিজেই যদি ঠিক থাকে তবে কীভাবে এটি সমস্ত খারাপ হতে পারে।
জন জে ওবারমার্ক

ঠিক আছে, পাইথনে পদ্ধতি সমাধানের আদেশ (ডেটা সদস্যদের ক্ষেত্রেও প্রযোজ্য) খুব সহজ নয় simple উদাহরণ স্তরে যা পাওয়া যায় না, তা শ্রেণিবদ্ধ স্তরের অনুসন্ধান করা হবে, তারপরে বেস শ্রেণিগুলির মধ্যে ইত্যাদি a কিন্তু উদাহরণস্বরূপ পর্যায়ের পদ্ধতি আবদ্ধ উদাহরণস্বরূপ এর selfপ্রয়োজন না selfপাস করতে হবে, যখন শ্রেণী-স্তরের পদ্ধতি আনবাউন্ড এবং প্লেইন ফাংশন হিসাবে দেখা হয় defসময়, এবং গ্রহণ প্রথম আর্গুমেন্ট হিসাবে একটি দৃষ্টান্ত। সুতরাং এই বিভিন্ন জিনিস।
9000

আমি মনে করি AttributeErrorযে এটি বাগের চেয়ে একটি ভাল সংকেত। অন্যথায়, আপনি কোনওটিই গ্রাস করবেন না এবং অর্থহীন ফলাফল পাবেন। ক্ষেত্রে ক্ষেত্রে বিশেষভাবে গুরুত্বপূর্ণ, যেখানে বৈশিষ্ট্যগুলি সংজ্ঞায়িত করা হয়েছে __init__, সুতরাং একটি অনুপস্থিত বৈশিষ্ট্য (তবে শ্রেণি পর্যায়ে বিদ্যমান) কেবল বগি উত্তরাধিকারের ফলেই হতে পারে।
ডেভিডমাহ

@ ডেভিডমাহ: একটি সনাক্ত করা ত্রুটি একটি সনাক্ত করা ত্রুটির চেয়ে সর্বদা ভাল indeed আমি বলব যে যদি আপনাকে কোনও বৈশিষ্ট্য বানাতে হয় Noneএবং উদাহরণটি নির্মাণের মুহুর্তে এই মানটি বোঝায় না , আপনার আর্কিটেকচারে আপনার সমস্যা আছে এবং বৈশিষ্ট্যের মান বা এর প্রাথমিক মানের জীবনচক্রটি পুনর্বিবেচনা করতে হবে। মনে রাখবেন যে আপনার বৈশিষ্ট্যগুলি প্রাথমিকভাবে সংজ্ঞায়িত করে আপনি বাকী ক্লাসটি লেখার আগেই এই জাতীয় সমস্যাটি সনাক্ত করতে পারেন, কোডটি চালিয়ে দেওয়া যাক।
9000

মজা! মিসাইল! যাইহোক, আমি পুরোপুরি নিশ্চিত যে ক্লাস স্তরের ভার্সগুলি তৈরি করা এবং সেগুলি মিশ্রিত করা ঠিক আছে ... যতক্ষণ না ক্লাস স্তরে ডিফল্ট ইত্যাদি রয়েছে
এরিক অ্যারোনস্টি

18

ব্যক্তিগতভাবে আমি সদস্যদের __ init __ () পদ্ধতিতে সংজ্ঞায়িত করি। আমি তাদের ক্লাসের অংশে সংজ্ঞায়িত করার বিষয়ে ভাবি নি। তবে আমি সবসময় যা করি: আমি________ পদ্ধতিতে সমস্ত সদস্যকে দীক্ষা করি, এমনকি __ init__ পদ্ধতিতেও প্রয়োজন হয় না।

উদাহরণ:

class Person:
    def __init__(self, name, age):
        self._name = name
        self._age = age
        self._selected = None

   def setSelected(self, value):
        self._selected = value

আমি মনে করি সকল সদস্যকে এক জায়গায় সংজ্ঞায়িত করা জরুরী। এটি কোডটিকে আরও পঠনযোগ্য করে তোলে। এটি __ init __ () এর বাইরে হোক বা বাইরের, তা গুরুত্বপূর্ণ নয়। তবে একটি দলের পক্ষে কম কোডিং স্টাইলে কম বেশি প্রতিশ্রুতিবদ্ধ হওয়া জরুরী।

ওহ, এবং আপনি খেয়াল করতে পারেন যে আমি কখনই সদস্য ভেরিয়েবলগুলিতে "_" উপসর্গ যুক্ত করি।


13
আপনার কনস্ট্রাক্টরে সমস্ত মান সেট করা উচিত। মানটি যদি ক্লাসে নিজেই সেট করা থাকে তবে এটি উদাহরণগুলির মধ্যে ভাগ করা হবে যা কোনটির পক্ষে নয়, তবে বেশিরভাগ মানের জন্য নয়। সুতরাং এটি সম্পর্কে কিছু পরিবর্তন করবেন না। ;)
রিমকো হাসিং

4
প্যারামিটারগুলির জন্য ডিফল্ট মান এবং স্বেচ্ছাসেবী অবস্থানগত এবং মূলশব্দ যুক্তি নেওয়ার ক্ষমতা একে প্রত্যাশার তুলনায় অনেক কম বেদনাদায়ক করে তোলে। (এবং নির্মাণকে অন্য পদ্ধতিতে বা এমনকি একা একা ফাংশনগুলিতে অর্পণ করা সম্ভব) সুতরাং আপনার যদি সত্যিই একাধিক প্রেরণের প্রয়োজন হয় তবে আপনি এটিও করতে পারেন)।
শান ভিয়েরা

6
@ বনেডিক্ট পাইথনের অ্যাক্সেস নিয়ন্ত্রণ নেই। নেতৃস্থানীয় আন্ডারস্কোর বাস্তবায়ন বিশদের জন্য গৃহীত কনভেনশন। পিইপি 8 দেখুন ।
ডোভাল

3
@ দোভাল বিশিষ্ট নামগুলির সাথে উপসর্গের একটি অসাধারণ ভাল কারণ রয়েছে _: এটি ব্যক্তিগত বলে বোঝাতে! (এই থ্রেডের এত লোক কেন অন্য ভাষার সাথে পাইথনকে বিভ্রান্ত বা অর্ধ-বিভ্রান্ত করছে?)

1
আহ্, সুতরাং আপনি সেই সমস্ত বৈশিষ্ট্যগুলির মধ্যে একটি বা সমস্ত-বহিরাগত-ইন্টারেক্টিভ লোকের জন্য ফাংশনগুলি ... ভুল বোঝার জন্য দুঃখিত। এই শৈলীটি আমার কাছে সর্বদা অতিরিক্ত মনে হয় তবে এর নিম্নলিখিতগুলি রয়েছে a
জন জে ওবারমার্ক

11

এটি একটি খারাপ অভ্যাস। আপনার এই মানগুলির দরকার নেই, তারা কোডটিকে বিশৃঙ্খলা করে এবং এগুলি ত্রুটির কারণ হতে পারে।

বিবেচনা:

>>> class WithNone:
...   x = None
...   y = None
...   def __init__(self, x, y):
...     self.x = x
...     self.y = y
... 
>>> class InitOnly:
...   def __init__(self, x, y):
...     self.x = x
...     self.y = y
... 
>>> wn = WithNone(1,2)
>>> wn.x
1
>>> WithNone.x #Note that it returns none, no error
>>> io = InitOnly(1,2)
>>> InitOnly.x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: class InitOnly has no attribute 'x'

আমি যে 'ত্রুটি ঘটায়' কল করতে কঠোর চাপ দেওয়া হবে। এখানে 'x' রিকোয়েস্ট করার মাধ্যমে আপনি কী বোঝাতে চেয়েছেন তা অস্পষ্ট, তবে আপনি সম্ভবত খুব সম্ভবত প্রাথমিক মান চাইবেন।
জন জে ওবারমার্ক

আমার বিস্তৃত হওয়া উচিত ছিল যে এটি ভুলভাবে ব্যবহার করা হলে এটি একটি ত্রুটি ঘটায়।
দেনিথ

উচ্চতর ঝুঁকি এখনও কোনও বস্তুর সাথে আরম্ভ করা হচ্ছে। আসলেই কেউই নিরাপদ নয়। এটি কেবলমাত্র ত্রুটিটি ঘটায় যা হ'ল লম্পট-মস্তিষ্কের ব্যতিক্রমগুলি গিলে ফেলা।
জন জে ওবারমার্ক

1
ত্রুটিগুলির কারণ হতে ব্যর্থ হওয়া যদি ত্রুটিগুলি আরও গুরুতর সমস্যাগুলি প্রতিরোধ করতে পারে।
এরিক অ্যারোনস্টি

0

আমি "কিছুটা ডকাস্ট্রিংসের মতো," এর সাথে যাব এবং যতক্ষণ না এটি সর্বদাNone বা অন্য মানগুলির একটি সংকীর্ণ পরিসীমা, সমস্ত অপরিবর্তনীয় ততক্ষণ এটিকে নির্দোষ বলে ঘোষণা করব ।

এটি অ্যাটভিজম এবং স্ট্যাটিকালি টাইপ করা ভাষাগুলির সাথে অত্যধিক সংযুক্তির সন্ধান করে। এবং এটি কোড হিসাবে কোনও ভাল করে না। ডকুমেন্টেশনে এটির একটি গৌণ উদ্দেশ্য রয়েছে।

এটি প্রত্যাশিত নামগুলি কী তা নথিভুক্ত করে, তাই যদি আমি কারও সাথে কোড যুক্ত করি এবং আমাদের মধ্যে একটির 'ব্যবহারকারীর নাম' এবং অন্য ব্যবহারকারীর নাম রয়েছে, মানুষের কাছে একটি চিহ্ন রয়েছে যে আমরা পৃথক হয়েছি এবং একই ভেরিয়েবলগুলি ব্যবহার করছি না।

নীতি হিসাবে সম্পূর্ণ সূচনা জোর করা আরও বেশি পাইথোনিক উপায়ে একই জিনিস অর্জন করে, তবে যদি সেখানে প্রকৃত কোড থাকে তবে এটি __init__ব্যবহারের ভেরিয়েবলগুলি নথিভুক্ত করার জন্য আরও পরিষ্কার জায়গা সরবরাহ করে।

স্পষ্টতই এখানে বিআইজি সমস্যাটি হ'ল এটি লোককে অন্য মানগুলির সাথে আরম্ভ করতে প্ররোচিত করে None, যা খারাপ হতে পারে:

class X:
    v = {}
x = X()
x.v[1] = 2

গ্লোবাল ট্রেস ছেড়ে যায় এবং এক্স এর জন্য উদাহরণ তৈরি করে না।

তবে এটি পুরোপুরি পাইথনের মধ্যে এই চর্চার চেয়ে বেশি উদ্ভট, এবং ইতিমধ্যে আমাদের এটি সম্পর্কে অসতর্ক হওয়া উচিত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.