পাইথন "সম্পত্তি" এবং "গুণাবলী" এর মধ্যে পার্থক্য কী?


146

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

উত্তর:


184

বৈশিষ্ট্য একটি বিশেষ ধরণের বৈশিষ্ট্য। মূলত, যখন পাইথন নিম্নলিখিত কোডের মুখোমুখি হয়:

spam = SomeObject()
print(spam.eggs)

এটি আপ দেখায় eggsমধ্যে spam, এবং তারপর পরীক্ষা eggsযদি এটি একটি হয়েছে দেখতে __get__, __set__বা __delete__পদ্ধতি - সেটা না হলে, এটি একটি সম্পত্তি আছে। যদি হয় একটি সম্পত্তি, পরিবর্তে শুধুমাত্র ফিরে eggsবস্তু (যেমন would অন্য কোন অ্যাট্রিবিউট জন্য) এটা ডাকব __get__পদ্ধতি এবং বিনিময়ে যাই হোক না কেন যে পদ্ধতি আয় (যেহেতু আমরা লুকআপ করছিলে)।

পাইথনের ডেটা মডেল এবং বর্ণনাকারীদের সম্পর্কে আরও তথ্য ।


দেখে মনে হচ্ছে বৈশিষ্ট্যগুলি লক্ষ্য মানটি অ্যাক্সেস করতে অতিরিক্ত প্রক্রিয়াজাতকরণ জড়িত ... আপনি কি জানেন যে এটি কতটা তাত্পর্যপূর্ণ / ধীর গতিযুক্ত?
মার্টিনিউ

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

56

একটি সম্পত্তি দিয়ে আপনার গেটর, সেটার এবং মুছে ফেলার পদ্ধতিগুলিতে আপনার সম্পূর্ণ নিয়ন্ত্রণ রয়েছে যা আপনার কোনও বৈশিষ্ট্যের সাথে (যদি সতর্কতা অবলম্বন না করে) থাকে না।

class A(object):
    _x = 0
    '''A._x is an attribute'''

    @property
    def x(self):
        '''
        A.x is a property
        This is the getter method
        '''
        return self._x

    @x.setter
    def x(self, value):
        """
        This is the setter method
        where I can check it's not assigned a value < 0
        """
        if value < 0:
            raise ValueError("Must be >= 0")
        self._x = value

>>> a = A()
>>> a._x = -1
>>> a.x = -1
Traceback (most recent call last):
  File "ex.py", line 15, in <module>
    a.x = -1
  File "ex.py", line 9, in x
    raise ValueError("Must be >= 0")
ValueError: Must be >= 0

এটি ("সম্পূর্ণ নিয়ন্ত্রণ") কেবলমাত্র সাধারণ সজ্জিত ছাড়াই "অ-সম্পত্তি" বৈশিষ্ট্যগুলির সাথেও করা যেতে পারে।

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

এই উত্তরটি "পাইথনের জেন - লঙ্ঘন করে - সেখানে একটি হওয়া উচিত - এবং কেবলমাত্র একটির - এটি করার সুস্পষ্ট উপায়"। এক্স মান নির্ধারণের জন্য দুটি উপায় রয়েছে।
টিন লুউ

@ টিনলুউ - এক্স এর মান নির্ধারণের একমাত্র উপায়। _X এর মান নির্ধারণের একমাত্র উপায় way তারা একই জিনিস হ'ল বাস্তবায়ন বিশদ। এই শ্রেণীর বুদ্ধিমান ব্যবহারকারী _x ব্যবহার করে না।
শয়নকামরা

1
@ টিনলুউ - আমি মনে করি আমরা উভয়ই দৃষ্টিভঙ্গির বিপরীত প্রান্ত থেকে একই কথা বলছি। শ্রেণীর ব্যবহারকারীকে কেবল দেখতে হবে x। একমুখী. শ্রেণীর ব্যবহারকারী যদি _x সম্পর্কে জানতে পারেন তবে তারা এটি তাদের নিজের ঝুঁকিতে ব্যবহার করে।
শয়নকামরা

19

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

class MyObject(object):
    # This is a normal attribute
    foo = 1

    @property
    def bar(self):
        return self.foo

    @bar.setter
    def bar(self, value):
        self.foo = value


obj = MyObject()
assert obj.foo == 1
assert obj.bar == obj.foo
obj.bar = 2
assert obj.foo == 2
assert obj.bar == obj.foo

1
আপনি কি দয়া করে এই কোডটির প্রত্যাশিত ফলাফলটি উল্লেখ করতে পারেন?
হাসান ইকবাল

2
আপনি কি বোঝাতে চেয়েছেন? কোডের নীচে এটি না?
ছয়টি

12

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

উদাহরণস্বরূপ বলা যাক, আপনার একটি শ্রেণি ছিল যা আপনার প্রয়োজনীয় কোনও কিছুর জন্য কিছু x এবং y স্থানাঙ্ক রাখে। সেগুলি সেট করতে আপনি কিছু করতে চাইবেন:

myObj.x = 5
myObj.y = 10

এটি লেখার চেয়ে দেখার এবং চিন্তা করা অনেক সহজ:

myObj.setX(5)
myObj.setY(10)

সমস্যাটি হ'ল, যদি একদিন আপনার ক্লাসটি এমন পরিবর্তন হয় যে আপনাকে আপনার x এবং y কে কিছু মূল্য দিয়ে অফসেট করতে হবে? এখন আপনার নিজের শ্রেণীর সংজ্ঞা এবং কোডটি যেটিকে এটি বলেছে তার সবকটি পরিবর্তন করতে হবে যা সত্যই সময় সাপেক্ষ এবং ত্রুটির প্রবণ হতে পারে। পরেরটির পরিবর্তনের নমনীয়তা দেওয়ার সময় সম্পত্তিটি আপনাকে পূর্বের বাক্য গঠন ব্যবহার করতে দেয়।

পাইথনে, আপনি সম্পত্তি ফাংশন সহ গিটারগুলি, সেটটারগুলি এবং পদ্ধতিগুলি মুছতে পারেন। আপনি যদি কেবল পঠিত সম্পত্তি চান তবে এখানে একটি @ প্রপার্টি ডেকরেটারও রয়েছে যা আপনি নিজের পদ্ধতির উপরে জুড়ে দিতে পারেন।

http://docs.python.org/library/functions.html#property


ব্যবহারিক জ্ঞান তৈরি হয়েছে যে শুধুমাত্র উত্তর!
Dude156

8

আমি বার্ড ক্লিনের সাইট থেকে 2 টি পার্থক্য শিখেছি , সংক্ষেপে:

১. ডেটা এনক্যাপসুলেশন করার জন্য সম্পত্তি হ'ল সুবিধাজনক উপায়।

উদাহরণস্বরূপ: যদি আপনার অবজেক্টের সর্বজনীন বৈশিষ্ট্যের দৈর্ঘ্য থাকে তবে পরবর্তীতে, আপনার প্রকল্পের জন্য আপনাকে এটি আবদ্ধ করতে হবে, অর্থাত: এটি ব্যক্তিগতকে পরিবর্তন করুন এবং গিটার এবং সেটার সরবরাহ করুন => আপনাকে আগে লেখা অনেকগুলি কোড পরিবর্তন করতে হবে:

#Old codes
obj1.length=obj1.length+obj2.length
#New codes(Using private attibutes and getter and setter)
obj1.set_lenght(obj1.get_length()+obj2.get_length()) #=> this is ugly

আপনি যদি @ প্রপার্টি এবং @ lenght.setter => ব্যবহার করেন তবে আপনাকে সেই পুরানো কোডগুলি পরিবর্তন করার দরকার নেই

2. একটি সম্পত্তি একাধিক বৈশিষ্ট্য encapsulate করতে পারেন

class Person:
  def __init__(self, name, physic_health, mental_health):
    self.name=name
    self.__physic_health=physic_health #physic_health is real value in range [0, 5.0]
    self.__mental_health=mental_health #mental_health is real value in range [0, 5.0]
  @property
  def condition(self):
    health=self.__physic_health+self.__mental_health
    if(health<5.0):
      return "I feel bad!"
    elif health<8.0:
      return "I am ok!"
    else:
      return "Great!"

এই উদাহরণে, __physic_healthএবং __mental_healthব্যক্তিগত হয় এবং বাইরে থেকে সরাসরি অ্যাক্সেস করা যায় না, শ্রেণীর বাইরের সাথে তাদের সাথে যোগাযোগ করার একমাত্র উপায় হ'ল সম্পত্তি মাধ্যমেcondition


8

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

class Misc():
        def __init__(self):
            self.test = self.test_func()

        def test_func(self):
            print 'func running'
            return 'func value'

cl = Misc()
print cl.test
print cl.test

আউটপুট:

func running
func value
func value

আমরা গুণটি দুটিবার অ্যাক্সেস করেছি তবে আমাদের ফাংশনটি কেবল একবারই বরখাস্ত করা হয়েছিল। সম্পত্তি ব্যবহার করার জন্য উপরের উদাহরণটি পরিবর্তন করা যখনই আপনি এটি অ্যাক্সেস করবেন ততবার গুণাবলীর মান রিফ্রেশ করবে:

class Misc():

    @property
    def test(self):
        print 'func running'
        return 'func value'

cl = Misc()
print cl.test
print cl.test

আউটপুট:

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