পাইথন নাম ম্যাঙ্গালিং


108

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

পাইথনের ক্ষেত্রেও কি একই সত্য রয়েছে? আমি কি প্রথমে প্রতিটি বিষয়ে দুটি শীর্ষস্থানীয় আন্ডারস্কোর ব্যবহার করব এবং আমার প্রয়োজন হিসাবে কেবল তাদেরকে কম লুকানো (কেবলমাত্র একটি আন্ডারস্কোর) করা উচিত?

যদি কনভেনশনটি কেবল একটি আন্ডারস্কোর ব্যবহার করে থাকে তবে আমি যুক্তিটিও জানতে চাই।

জেবার্নার্ডোর জবাব আমি এখানে রেখেছিলাম । এটি ব্যাখ্যা করে যে আমি কেন এই প্রশ্নটি জিজ্ঞাসা করেছি এবং কেন পাইথন অন্যান্য ভাষার চেয়ে পৃথক কেন জানতে চাই:

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

উত্তর:


182

সন্দেহ হলে এটিকে "সর্বজনীন" ছেড়ে দিন - মানে, আপনার গুণাবলীর নামটি অস্পষ্ট করতে কোনও কিছু যুক্ত করবেন না। আপনার যদি কিছু অভ্যন্তরীণ মান সহ কোনও শ্রেণি থাকে তবে এটি নিয়ে মাথা ঘামান না। লেখার পরিবর্তে:

class Stack(object):

    def __init__(self):
        self.__storage = [] # Too uptight

    def push(self, value):
        self.__storage.append(value)

এটি ডিফল্টরূপে লিখুন:

class Stack(object):

    def __init__(self):
        self.storage = [] # No mangling

    def push(self, value):
        self.storage.append(value)

এটি নিশ্চিতভাবেই কাজগুলি করার একটি বিতর্কিত উপায়। পাইথন নবজাতকরা কেবল এটি ঘৃণা করে এমনকি কিছু পুরানো পাইথন ছেলেরাও এই ডিফল্টটিকে ঘৃণা করে - তবে এটি যে কোনও উপায়েই ডিফল্ট, সুতরাং আপনি অস্বস্তি বোধ করলেও আমি সত্যিই আপনাকে এটি অনুসরণ করার পরামর্শ দিচ্ছি।

আপনি যদি সত্যই বার্তাটি প্রেরণ করতে চান তবে "এটি স্পর্শ করতে পারছি না!" আপনার ব্যবহারকারীদের কাছে, সাধারণ উপায়টি হ'ল একটি আন্ডারস্কোর সহ ভেরিয়েবলের আগে । এটি কেবল একটি সম্মেলন, তবে লোকেরা এটি বুঝতে পারে এবং এই জাতীয় জিনিসগুলির সাথে লেনদেন করার সময় দ্বিগুণ যত্ন নেয়:

class Stack(object):

    def __init__(self):
        self._storage = [] # This is ok but pythonistas use it to be relaxed about it

    def push(self, value):
        self._storage.append(value)

সম্পত্তির নাম এবং গুণবাচক নামের মধ্যে দ্বন্দ্ব এড়ানোর জন্য এটিও কার্যকর হতে পারে:

 class Person(object):
     def __init__(self, name, age):
         self.name = name
         self._age = age if age >= 0 else 0

     @property
     def age(self):
         return self._age

     @age.setter
     def age(self, age):
         if age >= 0:
             self._age = age
         else:
             self._age  = 0

ডাবল আন্ডারস্কোর সম্পর্কে কী? ঠিক আছে, ডাবল আন্ডারস্কোর যাদুটি প্রধানত ব্যবহৃত হয় দুর্ঘটনাজনিত অতিরিক্ত চাপ পড়তে এবং সুপারক্লাসের বৈশিষ্ট্যগুলির সাথে নাম দ্বন্দ্ব এড়াতে । আপনি যদি এমন একটি ক্লাস লিখেন যা অনেকবার বাড়ানো প্রত্যাশিত হয় তবে এটি বেশ কার্যকর হতে পারে।

আপনি যদি এটি অন্য উদ্দেশ্যে ব্যবহার করতে চান তবে আপনি এটি করতে পারেন তবে এটি স্বাভাবিক বা সুপারিশকৃত নয়।

সম্পাদনা : এমনটি কেন? ঠিক আছে, সাধারণ পাইথন শৈলী জিনিসগুলিকে ব্যক্তিগত করার উপর জোর দেয় না - বিপরীতে! এর অনেকগুলি কারণ রয়েছে - তাদের মধ্যে বেশিরভাগই বিতর্কিত ... আসুন আমরা তাদের কয়েকটি দেখে আসি।

পাইথনের বৈশিষ্ট্য রয়েছে

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

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

তাহলে এই ব্যক্তিগত-বাই-ডিফল্ট নীতিটি অনুসরণ করবেন কেন? কেবলমাত্র আপনার বৈশিষ্ট্যগুলি ডিফল্টরূপে সর্বজনীন করুন। অবশ্যই এটি জাভাতে সমস্যাযুক্ত কারণ আপনি যদি নিজের বৈশিষ্ট্যের সাথে কিছু বৈধতা যুক্ত করার সিদ্ধান্ত নেন তবে এটির জন্য আপনাকে সমস্ত পরিবর্তন করতে হবে

person.age = age;

আপনার কোডটিতে, আমাদের বলতে দিন,

person.setAge(age);

setAge() হচ্ছে:

public void setAge(int age) {
    if (age >= 0) {
        this.age = age;
    } else {
        this.age = 0;
    }
}

সুতরাং জাভাতে (এবং অন্যান্য ভাষাগুলি), ডিফল্টটি হ'ল যাইহোক getters এবং সেটার ব্যবহার করা, কারণ তারা লিখতে বিরক্ত করতে পারে তবে আমি বর্ণিত পরিস্থিতিতে যদি আপনি নিজেকে খুঁজে পান তবে আপনাকে অনেক সময় রক্ষা করতে পারে।

যাইহোক, পাইথনে আপনার এটি করার দরকার নেই, যেহেতু পাইথনের বৈশিষ্ট্য রয়েছে। আপনার যদি এই ক্লাস থাকে:

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

এবং তারপরে আপনি বয়সগুলি যাচাই করার সিদ্ধান্ত নেন person.age = age, আপনার কোডের টুকরো পরিবর্তন করার দরকার নেই । কেবল একটি সম্পত্তি যুক্ত করুন (নীচে দেখানো হয়েছে)

 class Person(object):
     def __init__(self, name, age):
         self.name = name
         self._age = age if age >= 0 else 0

     @property
     def age(self):
         return self._age

     @age.setter
     def age(self, age):
         if age >= 0:
             self._age = age
         else:
             self._age  = 0

আপনি যদি এটি করতে পারেন এবং এখনও ব্যবহার করতে পারেন person.age = age করতে পারেন তবে আপনি ব্যক্তিগত ক্ষেত্র এবং গিটারগুলি এবং সেটটারগুলি যুক্ত করবেন কেন?

(এছাড়াও, দেখুন পাইথন জাভা নয় এবং এই নিবন্ধটি গেটার এবং সেটারগুলি ব্যবহারের ক্ষতির বিষয়ে ।)

যাইহোক সবকিছু দৃশ্যমান - এবং লুকানোর চেষ্টা আপনার কাজকে জটিল করে তোলে

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

পাইথন যেহেতু খুব গতিশীল ভাষা, তাই এই ভারটিকে আপনার ক্লাসে যুক্ত করা কেবল প্রতি-উত্পাদক।

সমস্যাটি দেখা সম্ভব হচ্ছে না - এটি প্রয়োজন required দেখার

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

এখন, আপনি যদি নিজের ক্লাসটি এমনভাবে লিখে থাকেন তবে আপনি প্রয়োগের বিশদ সম্পর্কে চিন্তা না করেই এটি ব্যবহার করতে পারেন, আপনি চাইলে কোনও সমস্যা নেই কোনও কারণে ক্লাসের ভিতরে । কথাটি হ'ল: আপনার এপিআই ভাল হওয়া উচিত এবং বাকিটি বিশদ।

গুডো তাই বলেছিল

ঠিক আছে, এটি বিতর্কিত নয়: তিনি আসলে তাই বলেছিলেন । ("উন্মুক্ত কিমোনো।" দেখুন)

এটাই সংস্কৃতি

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

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


1. এনক্যাপসুলেশন শ্রেণি আক্রমণকারীদের রক্ষার জন্য। বাহ্যিক পৃথিবী থেকে অপ্রয়োজনীয় বিশদগুলি গোপন না করা কারণ এটি বিরক্তিকর হবে। 2. "মুল বক্তব্যটি হল: আপনার এপিআই ভাল হওয়া উচিত এবং বাকী বিশদ বিবরণ।" এটা সত্য. এবং সর্বজনীন বৈশিষ্ট্যগুলি আপনার API এর অংশ part এছাড়াও, কখনও কখনও পাবলিক সেটটারগুলি উপযুক্ত (আপনার শ্রেণীর আক্রমণকারীদের ক্ষেত্রে) এবং কখনও কখনও তা হয় না। এমন একটি এপিআই, যাতে সর্বজনীন সেটেটর থাকে যা সর্বজনীন হওয়া উচিত নয় (আক্রমণকারীদের লঙ্ঘনের ঝুঁকি) একটি খারাপ API। এর অর্থ আপনাকে যে কোনও উপায়ে প্রতিটি সেটারের দৃশ্যমানতা সম্পর্কে ভাবতে হবে এবং একটি 'ডিফল্ট' অর্থ কম হওয়া মানে।
বৃহস্পতি

21

প্রথম - নাম ম্যাঙ্গালিং কী?

নাম mangling প্রার্থনা যখন আপনি একটি বর্গ সংজ্ঞা এবং ব্যবহার করা হচ্ছে হয় __any_nameবা __any_name_, যে, দুই এবং নেতৃস্থানীয় আন্ডারস্কোর (বা তার বেশি) সর্বাধিক এক আন্ডারস্কোর trailing।

class Demo:
    __any_name = "__any_name"
    __any_other_name_ = "__any_other_name_"

এবং এখন:

>>> [n for n in dir(Demo) if 'any' in n]
['_Demo__any_name', '_Demo__any_other_name_']
>>> Demo._Demo__any_name
'__any_name'
>>> Demo._Demo__any_other_name_
'__any_other_name_'

সন্দেহ হলে, কি করবেন?

অস্টেনসিবল ব্যবহার হ'ল সাবক্ল্যাসারদের ক্লাসটি ব্যবহার করে এমন একটি বৈশিষ্ট্য ব্যবহার করা থেকে বিরত রাখা।

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

ডাউনসাইডগুলি হ'ল এটি কোনও কোড বেস পড়ার এবং বোঝার জন্য জ্ঞানীয় লোড বাড়িয়ে তোলে এবং বিশেষত তাই যেখানে আপনি উত্সটিতে ডাবল আন্ডারস্কোর নাম এবং ডিবাগারটিতে একটি ম্যাংগলড নাম দেখেন deb

আমার ব্যক্তিগত দৃষ্টিভঙ্গি এটি ইচ্ছাকৃতভাবে এড়ানো avoid আমি খুব বড় কোড বেসে কাজ করি। এর বিরল ব্যবহারগুলি কালশিটে থাম্বের মতো লেগে থাকে এবং ন্যায়সঙ্গত বলে মনে হয় না।

আপনার এটি সম্পর্কে সচেতন হওয়া দরকার তাই আপনি এটি দেখলেই তা জানবেন।

পিইপি 8

পাইথ 8 , পাইথন স্ট্যান্ডার্ড লাইব্রেরি স্টাইল গাইড বর্তমানে বলেছেন (সংক্ষিপ্ত):

ব্যবহার সম্পর্কে কিছু বিতর্ক আছে __names

যদি আপনার ক্লাসটি সাবক্ল্যাসড করার উদ্দেশ্যে থাকে এবং আপনার এমন বৈশিষ্ট্য রয়েছে যা আপনি সাবক্লাস ব্যবহার করতে চান না তবে তাদের ডাবল লিডিং আন্ডারস্কোর এবং কোনও পেছনের আন্ডারস্কোর সহ নামকরণ বিবেচনা করুন।

  1. মনে রাখবেন যে কেবল সাধারণ শ্রেণীর নামটি ম্যাংলেড নামে ব্যবহৃত হয়, সুতরাং যদি একটি সাবক্লাস একই শ্রেণির নাম এবং বৈশিষ্ট্য নাম উভয়ই চয়ন করে তবে আপনি নামের সংঘর্ষ পেতে পারেন।

  2. নাম ম্যাঙ্গালিং নির্দিষ্ট ব্যবহার করতে পারে যেমন ডিবাগিং এবং __getattr__()কম সুবিধাজনক। তবে ম্যাংলিং অ্যালগরিদম নামটি ভালভাবে নথিভুক্ত এবং ম্যানুয়ালি সম্পাদন করা সহজ।

  3. সবাই নাম ম্যাঙ্গালিং পছন্দ করে না। উন্নত কলারদের দ্বারা সম্ভাব্য ব্যবহারের সাথে দুর্ঘটনাজনিত নাম সংঘর্ষ এড়াতে প্রয়োজনীয়তার ভারসাম্য বজায় রাখার চেষ্টা করুন।

এটা কিভাবে কাজ করে?

আপনি যদি শ্রেণীর সংজ্ঞায় দুটি আন্ডারস্কোর (ডাবল-আন্ডারস্কোর শেষ না করে) প্রিপেন্ড করেন তবে নামটি ম্যাঙ্গেল করা হবে এবং শ্রেণীর নাম অনুসারে একটি আন্ডারস্কোরটি বস্তুর উপরে চাপ দেওয়া হবে:

>>> class Foo(object):
...     __foobar = None
...     _foobaz = None
...     __fooquux__ = None
... 
>>> [name for name in dir(Foo) if 'foo' in name]
['_Foo__foobar', '__fooquux__', '_foobaz']

মনে রাখবেন শ্রেণি সংজ্ঞাটি বিশ্লেষণ করা হলে কেবল নামগুলি ম্যাঙ্গেল হবে:

>>> Foo.__test = None
>>> Foo.__test
>>> Foo._Foo__test
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute '_Foo__test'

এছাড়াও, পাইথন-এ নতুন যারা কখনও কখনও শ্রেণীর সংজ্ঞায় সংজ্ঞায়িত যে নামটি ম্যানুয়ালি কোনও নাম অ্যাক্সেস করতে না পারছেন তখন কী হচ্ছে তা বুঝতে সমস্যা হয় have এটি এর বিরুদ্ধে একটি শক্ত কারণ নয়, তবে আপনার যদি শিখার শ্রোতা থাকে তবে এটি বিবেচনা করার মতো বিষয়।

ওয়ান ইন্ডস্কোর?

যদি কনভেনশনটি কেবল একটি আন্ডারস্কোর ব্যবহার করে থাকে তবে আমি যুক্তিটিও জানতে চাই।

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

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


15

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

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

পাইথনে আমার কৌশলটি হ'ল:

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

সর্বোপরি, সবকিছু কী করে তা পরিষ্কার হওয়া উচিত। অন্য কেউ এটি ব্যবহার করে থাকলে এটি নথি করুন। আপনি যদি এটি এক বছরের ব্যবস্থায় কার্যকর হতে চান তবে এটি নথি করুন।

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


9

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

অন্য ভাষাগুলি যেগুলি একসময় প্রকাশ্যে ছিল তা ব্যক্তিগত করা কঠিন করে তোলে। অর্থাৎ আমি আমার পরিবর্তনশীলটিকে ব্যক্তিগত বা সুরক্ষিত রাখলে আমি প্রচুর কোড ভাঙবো। কিন্তু পাইথনে থাকা সম্পত্তিগুলির ক্ষেত্রে এটি হয় না। বরং অভ্যন্তরীণ ডেটা পুনর্বিন্যাস করেও আমি একই ইন্টারফেস বজায় রাখতে পারি।

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


6

এর জন্য ইতিমধ্যে অনেক ভাল উত্তর রয়েছে, তবে আমি অন্য একটি প্রস্তাব দিতে যাচ্ছি। এটি আংশিকভাবে এমন লোকদের প্রতিক্রিয়া যা যারা বলে যে ডাবল আন্ডারস্কোরটি ব্যক্তিগত নয় (এটি সত্যই)।

আপনি যদি জাভা / সি # তে লক্ষ্য করেন তবে উভয়েরই ব্যক্তিগত / সুরক্ষিত / সর্বজনীন। এই সব সংকলন-সময় নির্মাণ । এগুলি কেবল সংকলনের সময় প্রয়োগ করা হয়। আপনি যদি জাভা / সি # তে প্রতিবিম্ব ব্যবহার করেন তবে আপনি সহজেই ব্যক্তিগত পদ্ধতিতে অ্যাক্সেস করতে পারবেন।

এখন যখনই আপনি পাইথনে কোনও ফাংশন কল করবেন তখন আপনি সহজাতভাবে প্রতিচ্ছবি ব্যবহার করছেন। এই কোডগুলির টুকরা পাইথনে একই।

lst = []
lst.append(1)
getattr(lst, 'append')(1)

"ডট" সিনট্যাক্সটি কেবল কোডটির পরবর্তী অংশের জন্য সিনট্যাকটিক চিনি। বেশিরভাগ কারণেই getattr ব্যবহার করা কেবলমাত্র একটি ফাংশন কল দিয়ে ইতিমধ্যে কুৎসিত। এটি সেখান থেকে আরও খারাপ হয়।

সুতরাং যে, সেখানে পারে না ব্যক্তিগত জাভা / সি # সংস্করণ , কারণ পাইথন কোডটি সংকলন করে না। জাভা এবং সি # কোনও তথ্য কোনও রান ব্যক্তিগত সময়ে ব্যক্তিগত বা সর্বজনীন কিনা তা যাচাই করতে পারে না, কারণ সেই তথ্যটি চলে গেছে (এবং ফাংশনটি কোথা থেকে ডেকে আনা হচ্ছে তার কোনও জ্ঞান নেই)।

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

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


4

প্রথম: আপনি কেন আপনার তথ্য গোপন করতে চান? কেন এত গুরুত্বপূর্ণ?

বেশিরভাগ সময় আপনি এটি করতে চান না তবে অন্যরা করছেন বলে আপনি তা করেন।

আপনি যদি সত্যিই সত্যিই লোকেরা কিছু ব্যবহার করতে না চান তবে একটি যুক্ত করুন এর সামনে আন্ডারস্কোর । পাইথনিস্টরা জানেন যে এক আন্ডারস্কোরযুক্ত জিনিসগুলি প্রতিবার কাজ করার গ্যারান্টিযুক্ত নয় এবং আপনাকে না জেনে পরিবর্তিত হতে পারে।

আমরা যেভাবে বেঁচে আছি সেই পথেই আমরা ঠিক আছি।

দুটি আন্ডারস্কোর ব্যবহার আপনার ক্লাসটিকে সাবক্লাসের পক্ষে এতটাই খারাপ করে তুলবে যে এমনকি আপনি সেভাবে কাজ করতে চাইবেন না।


2
সাবক্লাসিংয়ের জন্য ডাবল আন্ডারস্কোর খারাপ হওয়ার কারণটি আপনি বাদ দিয়েছেন ... এটি আপনার উত্তরকে উন্নত করবে।
ম্যাট জয়েনার

2
প্রদত্ত যে ডাবল আন্ডারস্কোরগুলি কেবলমাত্র সাবক্ল্যাসারদের সাথে নাম সংঘর্ষ রোধ করার জন্য ("হ্যান্ড অফ", "সাবক্ল্যাসার্সকে বলার উপায় হিসাবে), আমি দেখতে পাচ্ছি না কীভাবে নাম মাংলিঙ একটি সমস্যা তৈরি করে।
অ্যারন হল

4

নির্বাচিত উত্তরটি কীভাবে বৈশিষ্ট্যগুলি ব্যক্তিগত বৈশিষ্ট্যগুলির প্রয়োজনীয়তা অপসারণ করে তা বোঝানোর জন্য একটি ভাল কাজ করে তবে আমি মডিউল স্তরে এই ফাংশনগুলিকে ব্যক্তিগত পদ্ধতির প্রয়োজনীয়তা অপসারণ করতে চাই ।

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


3

নিম্নলিখিত কোড স্নিপেট সমস্ত বিভিন্ন ক্ষেত্রে ব্যাখ্যা করবে:

  • দুটি শীর্ষস্থানীয় আন্ডারস্কোর (__a)
  • একক শীর্ষস্থানীয় আন্ডারস্কোর (_এ)
  • কোন আন্ডারস্কোর (ক)

    class Test:
    
    def __init__(self):
        self.__a = 'test1'
        self._a = 'test2'
        self.a = 'test3'
    
    def change_value(self,value):
        self.__a = value
        return self.__a

টেস্ট অবজেক্টের সমস্ত বৈধ বৈশিষ্ট্য মুদ্রণ

testObj1 = Test()
valid_attributes = dir(testObj1)
print valid_attributes

['_Test__a', '__doc__', '__init__', '__module__', '_a', 'a', 
'change_value']

এখানে, আপনি দেখতে পাচ্ছেন যে এই ভেরিয়েবলটি যে কোনও সাবক্লাসের দ্বারা ওভাররাইড হওয়া থেকে রোধ করতে __a এর নামটি পরিবর্তিত হয়ে __est__a করা হয়েছে। এই ধারণাটি পাইথনে "নেম মংলিং" নামে পরিচিত। আপনি এটির এভাবে অ্যাক্সেস করতে পারেন:

testObj2 = Test()
print testObj2._Test__a

test1

একইভাবে, _a এর ক্ষেত্রে, চলকটি কেবল বিকাশকারীকে অবহিত করতে হয় যে এটি class শ্রেণীর অভ্যন্তরীণ ভেরিয়েবল হিসাবে ব্যবহার করা উচিত, অজগর দোভাষী আপনি এটি অ্যাক্সেস করলেও কিছু করতে পারবেন না, তবে এটি একটি ভাল অভ্যাস নয়।

testObj3 = Test()
print testObj3._a

test2

ভেরিয়েবলটি যে কোনও জায়গা থেকে অ্যাক্সেস হতে পারে এটি পাবলিক ক্লাস ভেরিয়েবলের মতো।

testObj4 = Test()
print testObj4.a

test3

আশা করি উত্তরটি আপনাকে সহায়তা করেছে :)


2

প্রথম নজরে এটি অন্যান্য ভাষার মতোই হওয়া উচিত ("অন্যান্য" এর অর্থ জাভা বা সি ++ এর অর্থ) তবে এটি তা নয়।

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

সুতরাং, আমি আপনাকে "ব্যক্তিগত" সদস্যদের জন্য ডিফল্টরূপে একক আন্ডারস্কোর ব্যবহার করার পরামর্শ দিই।


"ব্যক্তিগত" জন্য ডাবল আন্ডারস্কোর এবং "সুরক্ষিত" জন্য একক আন্ডারস্কোর ব্যবহার করুন। সাধারণত, লোকেরা কেবলমাত্র প্রতিটি কিছুর জন্য একক আন্ডারস্কোর ব্যবহার করে (ডাবল আন্ডারস্কোর বেসরকারীতা প্রয়োগে সহায়তা করবে, যা সাধারণত পাইথন শৈলীর বিপরীতে থাকে)।
জোনাথন স্টার্নবার্গ

1
তবে এটি কি দুটি আন্ডারস্কোর ব্যক্তিগত এবং একইরকম একটি আন্ডারস্কোরকে সুরক্ষিত করার মতো করে না? শুধু "বেসরকারী" থেকে শুরু করবেন না কেন?
পল মান্টা

@ পল না, এটি হয় না। পাইথনে কোনও ব্যক্তিগত নেই এবং এটি অর্জনের চেষ্টা করা উচিত নয়।
রোমান বোদনারচুক

@ রোমান ধারণাগতভাবে কথা বলছেন ... 'ব্যক্তিগত' এর আশেপাশে উদ্ধৃতিগুলি লক্ষ্য করুন Notice
পল মানতা

1

"কোনও ভেরিয়েবলটি ব্যক্তিগত বা সুরক্ষিত হওয়া উচিত কিনা তা নিয়ে সন্দেহ থাকলে, ব্যক্তিগত সাথে যাওয়া ভাল" " - হ্যাঁ, পাইথনেও একই জিনিস।

কিছু উত্তর এখানে 'সম্মেলনগুলি' সম্পর্কে বলে, কিন্তু সেই সম্মেলনগুলির লিঙ্কগুলি দেবে না। পাইথনের অনুমোদনের গাইড, পিইপি 8 স্পষ্টভাবে জানিয়েছে:

সন্দেহ হলে, জনসাধারণকে বেছে নিন; সর্বজনীন বৈশিষ্ট্যটিকে অ-জনসাধারণের চেয়ে পরে এটিকে প্রকাশ্য করা আরও সহজ।

পাইথনে পাবলিক এবং প্রাইভেট এবং নাম ম্যাংলিংয়ের মধ্যে পার্থক্য অন্যান্য উত্তরে বিবেচনা করা হয়েছে। একই লিঙ্ক থেকে,

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

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