python - @ প্রপার্টি শোভাকর কিভাবে কাজ করে?




properties decorator (8)

আমি এখানে সব পোস্ট পড়েছি এবং উপলব্ধি করেছি যে আমাদের প্রকৃত জীবন উদাহরণ প্রয়োজন হতে পারে, কেন, আসলে, আমাদের @property আছে? সুতরাং, একটি ফ্লাস্ক অ্যাপ্লিকেশন বিবেচনা করুন যেখানে আপনি প্রমাণীকরণ সিস্টেম ব্যবহার করেন। আপনি models.py : একটি মডেল ব্যবহারকারী ঘোষণা করেছেন

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), unique=True, index=True)
    username = db.Column(db.String(64), unique=True, index=True)
    password_hash = db.Column(db.String(128))

    ...

    @property
    def password(self):
        raise AttributeError('password is not a readable attribute')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

এই @property ব্যবহার করে "লুকানো" বৈশিষ্ট্যটি করেছি যা AttributeError কথোপকথনটিকে সরাসরি অ্যাক্সেস করার সময় ট্রিগার করে, যখন আমরা @ property.setter ব্যবহার করে প্রকৃত ইনস্ট্যান্সের পরিবর্তনশীল password_hash সেট করি।

এখন auth/views.py আমরা একটি ব্যবহারকারীকে তাত্ক্ষণিকভাবে তাত্ক্ষণিকভাবে যুক্ত করতে পারি:

...
@auth.route('/register', methods=['GET', 'POST'])
def register():
    form = RegisterForm()
    if form.validate_on_submit():
        user = User(email=form.email.data,
                    username=form.username.data,
                    password=form.password.data)
        db.session.add(user)
        db.session.commit()
...

ব্যবহারকারীর ফর্মটি পূরণ করার সময় রেজিস্ট্রেশন ফর্ম থেকে আসে এমন নোটিফিকেশন password লক্ষ্য করুন। পাসওয়ার্ড নিশ্চিতকরণ EqualTo('password', message='Passwords must match') সাথে সামনের প্রান্তে ঘটবে (যদি আপনি হতাশ হন তবে এটি একটি আলাদা বিষয় ফ্লাস ফর্মগুলির সাথে সম্পর্কিত)।

আমি এই উদাহরণ দরকারী হবে আশা করি

আমি অন্তর্নির্মিত ফাংশন property কাজ কিভাবে বুঝতে চাই। আমার কি বিভ্রান্তিকর যে property একটি শোভাকর হিসাবেও ব্যবহার করা যেতে পারে, তবে বিল্ট-ইন ফাংশন হিসাবে ব্যবহৃত হলে এটি শুধুমাত্র আর্গুমেন্টগুলি নেয় এবং কোন সজ্জাকারী হিসাবে ব্যবহৃত হয় না।

এই উদাহরণটি documentation থেকে:

class C(object):
    def __init__(self):
        self._x = None

    def getx(self):
        return self._x
    def setx(self, value):
        self._x = value
    def delx(self):
        del self._x
    x = property(getx, setx, delx, "I'm the 'x' property.")

property এর আর্গুমেন্ট getx , setx , delx এবং একটি ডক স্ট্রিং হয়।

নীচের কোডে property সজ্জা হিসাবে ব্যবহার করা হয়। এটির বস্তুটি x ফাংশন, তবে উপরের কোডটিতে আর্গুমেন্টগুলিতে বস্তুর ফাংশনের জন্য কোনও স্থান নেই।

class C(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x

এবং, x.setter এবং x.deleter decorators x.deleter তৈরি হয়? আমি দ্বিধান্বিত.


আসুন পাইথন সজ্জাকারীদের সাথে শুরু করি।

একটি পাইথন সজ্জাকারী একটি ফাংশন যা ইতিমধ্যে সংজ্ঞায়িত ফাংশনে কিছু অতিরিক্ত কার্যকারিতা যোগ করতে সহায়তা করে।

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

নিম্নলিখিত কোড স্নিপেট বিবেচনা করুন।

def decorator_func(fun):
    def wrapper_func():
        print("Wrapper function started")
        fun()
        print("Given function decorated")
        # Wrapper function add something to the passed function and decorator 
        # returns the wrapper function
    return wrapper_func

def say_bye():
    print("bye!!")

say_bye = decorator_func(say_bye)
say_bye()

# Output:
#  Wrapper function started
#  bye
#  Given function decorated

এখানে, আমরা বলতে পারি যে শোভাকর ফাংশনটি আমাদের say_hello ফাংশনটি সংশোধন করেছে এবং এতে কিছু অতিরিক্ত লাইন যোগ করেছে।

সজ্জা জন্য পাইথন সিনট্যাক্স

def decorator_func(fun):
    def wrapper_func():
        print("Wrapper function started")
        fun()
        print("Given function decorated")
        # Wrapper function add something to the passed function and decorator 
        # returns the wrapper function
    return wrapper_func

@decorator_func
def say_bye():
    print("bye!!")

say_bye()

আসুন একটি দৃশ্যকল্প দৃশ্যকল্প সঙ্গে সবকিছু শেষ করা যাক, কিন্তু এর আগে এর কিছু principiples সম্পর্কে কথা বলা যাক।

ডেটা ইনકેપসুলেশন নীতিটি নিশ্চিত করার জন্য অনেক বস্তু ভিত্তিক প্রোগ্রামিং ভাষাগুলিতে গেটস এবং সেট্টারগুলি ব্যবহার করা হয় (এই ডেটাতে যে পদ্ধতিগুলি পরিচালনা করে তার সাথে তথ্যগুলির বান্ডলিং হিসাবে দেখা হয়।)

তথ্যগুলি পরিবর্তন করার জন্য এই পদ্ধতিগুলি অবশ্যই ডেটার এবং সেটার পুনরুদ্ধারের জন্য প্রাপক।

এই নীতির মতে, একটি শ্রেণির বৈশিষ্ট্যগুলিকে গোপন করে অন্য কোড থেকে রক্ষা করার জন্য ব্যক্তিগত করা হয়।

Yup, @property মূলত Gator এবং Setters ব্যবহার করার জন্য একটি পাইথনিক উপায়।

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

আসুন আমরা অনুমান করি যে আপনি এমন একটি বর্গ তৈরি করার সিদ্ধান্ত নেন যা ডিগ্রী সেলসিয়াস তাপমাত্রা সঞ্চয় করতে পারে।

class Celsius:
def __init__(self, temperature = 0):
    self.set_temperature(temperature)

def to_fahrenheit(self):
    return (self.get_temperature() * 1.8) + 32

def get_temperature(self):
    return self._temperature

def set_temperature(self, value):
    if value < -273:
        raise ValueError("Temperature below -273 is not possible")
    self._temperature = value

প্রত্যয়িত কোড, এখানে আমরা সম্পত্তি সঙ্গে এটি অর্জন করতে পারে কিভাবে।

পাইথন ইন, সম্পত্তি () একটি অন্তর্নির্মিত ফাংশন যা একটি সম্পত্তি বস্তু তৈরি করে এবং প্রদান করে।

একটি সম্পত্তি বস্তুর তিনটি পদ্ধতি আছে, getter (), setter (), এবং মুছে ফেলুন ()।

class Celsius:
def __init__(self, temperature = 0):
    self.temperature = temperature

def to_fahrenheit(self):
    return (self.temperature * 1.8) + 32

def get_temperature(self):
    print("Getting value")
    return self.temperature

def set_temperature(self, value):
    if value < -273:
        raise ValueError("Temperature below -273 is not possible")
    print("Setting value")
    self.temperature = value

temperature = property(get_temperature,set_temperature)

এখানে,

temperature = property(get_temperature,set_temperature)

হিসাবে ভাঙ্গা হতে পারে,

# make empty property
temperature = property()
# assign fget
temperature = temperature.getter(get_temperature)
# assign fset
temperature = temperature.setter(set_temperature)

উল্লেখ্য পয়েন্ট:

  • get_temperature একটি পদ্ধতি পরিবর্তে একটি সম্পত্তি অবশেষ।

এখন আপনি লেখার মাধ্যমে তাপমাত্রার মান অ্যাক্সেস করতে পারেন।

C = Celsius()
C.temperature
# instead of writing C.get_temperature()

আমরা আরও যেতে এবং নামগুলি def_temperature এবং set_temperature সংজ্ঞায়িত করতে পারি না কারণ এটি অপ্রয়োজনীয় এবং শ্রেণী নামস্থান দূষিত করে।

উপরের সমস্যাটি মোকাবেলা করার জন্য পাইথনিক উপায় @property ব্যবহার করা।

class Celsius:
    def __init__(self, temperature = 0):
        self.temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

    @property
    def temperature(self):
        print("Getting value")
        return self.temperature

    @temperature.setter
    def temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        print("Setting value")
        self.temperature = value

উল্লেখ্য পয়েন্ট -

  1. একটি মান পাওয়ার জন্য ব্যবহৃত একটি পদ্ধতি "@property" দিয়ে সজ্জিত করা হয়।
  2. সেটটার হিসাবে কাজ করার পদ্ধতিটি "@ temperature.setter" দিয়ে সজ্জিত করা হয়, যদি ফাংশনটিকে "x" বলা হয়, তাহলে "@ x.setter" দিয়ে এটি সাজাইয়া রাখা হবে।
  3. আমরা একই নামের সাথে "দুই" পদ্ধতি এবং "ডিফেন্স তাপমাত্রা (স্ব)" এবং "ডিফ তাপমাত্রা (স্ব, এক্স)" এর বিভিন্ন পরিমানের প্যারামিটার লিখেছি।

আপনি দেখতে পারেন, কোড স্পষ্টভাবে কম মার্জিত হয়।

এখন, আসুন একটি বাস্তব জীবনের বাস্তব scenerio সম্পর্কে কথা বলা যাক।

চলুন আপনি নিম্নরূপ একটি ক্লাস ডিজাইন করেছেন বলে দিন:

class OurClass:

    def __init__(self, a):
        self.x = a


y = OurClass(10)
print(y.x)

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

এবং একটি ভাগ্যবান দিন, একটি বিশ্বস্ত ক্লায়েন্ট আমাদের কাছে এসেছিলেন এবং প্রস্তাব করেছিলেন যে "x" 0 এবং 1000 এর মধ্যে একটি মান হতে হবে, এটি সত্যিই একটি ভয়ঙ্কর দৃশ্য!

বৈশিষ্ট্যের কারণে এটি সহজ: আমরা "x" এর একটি সম্পত্তি সংস্করণ তৈরি করি।

class OurClass:

    def __init__(self,x):
        self.x = x

    @property
    def x(self):
        return self.__x

    @x.setter
    def x(self, x):
        if x < 0:
            self.__x = 0
        elif x > 1000:
            self.__x = 1000
        else:
            self.__x = x

এটি দুর্দান্ত, এটি নয়: আপনি কল্পনাযোগ্য সরল বাস্তবায়নের সাথে শুরু করতে পারেন এবং পরে ইন্টারফেস পরিবর্তন না করেই আপনি একটি সম্পত্তি সংস্করণে মাইগ্রেট করতে পারেন! সুতরাং সম্পত্তি পেতে এবং প্রতিষেধক জন্য একটি প্রতিস্থাপন হয় না!

আপনি here এই বাস্তবায়ন চেক করতে পারেন


এই বিন্দু অনেক লোকের দ্বারা সাফ করা হয়েছে কিন্তু এখানে আমি একটি সরাসরি পয়েন্ট যা অনুসন্ধান ছিল। @Property decorator এর সাথে শুরু করাটা আমার কাছে গুরুত্বপূর্ণ। উদাহরণ: -

class UtilityMixin():
    @property
    def get_config(self):
        return "This is property"

ফাংশন কলিং "get_config ()" এই মত কাজ করবে।

util = UtilityMixin()
print(util.get_config)

যদি আপনি লক্ষ্য করেন যে আমি ফাংশনটি কল করার জন্য "()" বন্ধনী ব্যবহার করি নি। এটি মূল জিনিস যা আমি @property decorator এর জন্য অনুসন্ধান করছিলাম। যাতে আপনি একটি পরিবর্তনশীল মত আপনার ফাংশন ব্যবহার করতে পারেন।


এক মন্তব্য: আমার জন্য, পাইথন 2.x এর জন্য, @ প্রোপার্টি বিজ্ঞাপনের মতো কাজ করে নি যখন আমি ফর্ম অবজেক্টের উত্তরাধিকারী নন:

class A():
    pass

কিন্তু কাজ যখন:

class A(object):
    pass

Pyhton 3 জন্য, সবসময় কাজ


এখানে আরেকটি উদাহরণ আছে:

##
## Python Properties Example
##
class GetterSetterExample( object ):
    ## Set the default value for x ( we reference it using self.x, set a value using self.x = value )
    __x = None


##
## On Class Initialization - do something... if we want..
##
def __init__( self ):
    ## Set a value to __x through the getter / setter... Since __x is defined above, this doesn't need to be set...
    self.x = 1234

    return None


##
## Define x as a property, ie a getter - All getters should have a default value arg, so I added it - it will not be passed in when setting a value, so you need to set the default here so it will be used..
##
@property
def x( self, _default = None ):
    ## I added an optional default value argument as all getters should have this - set it to the default value you want to return...
    _value = ( self.__x, _default )[ self.__x == None ]

    ## Debugging - so you can see the order the calls are made...
    print( '[ Test Class ] Get x = ' + str( _value ) )

    ## Return the value - we are a getter afterall...
    return _value


##
## Define the setter function for x...
##
@x.setter
def x( self, _value = None ):
    ## Debugging - so you can see the order the calls are made...
    print( '[ Test Class ] Set x = ' + str( _value ) )

    ## This is to show the setter function works.... If the value is above 0, set it to a negative value... otherwise keep it as is ( 0 is the only non-negative number, it can't be negative or positive anyway )
    if ( _value > 0 ):
        self.__x = -_value
    else:
        self.__x = _value


##
## Define the deleter function for x...
##
@x.deleter
def x( self ):
    ## Unload the assignment / data for x
    if ( self.__x != None ):
        del self.__x


##
## To String / Output Function for the class - this will show the property value for each property we add...
##
def __str__( self ):
    ## Output the x property data...
    print( '[ x ] ' + str( self.x ) )


    ## Return a new line - technically we should return a string so it can be printed where we want it, instead of printed early if _data = str( C( ) ) is used....
    return '\n'

##
##
##
_test = GetterSetterExample( )
print( _test )

## For some reason the deleter isn't being called...
del _test.x

মূলত, সি (বস্তু) উদাহরণের মতোই আমি ব্যতীত এক্স ব্যবহার করছি না ... আমি __init- তেও শুরু করি না ... ভাল .. আমি করি, কিন্তু এটি সরানো যেতে পারে কারণ __x অংশ হিসাবে সংজ্ঞায়িত করা হয় ক্লাসের ....

আউটপুট হয়:

[ Test Class ] Set x = 1234
[ Test Class ] Get x = -1234
[ x ] -1234

এবং যদি আমি init in self.x = 1234 টি মন্তব্য করি তবে আউটপুটটি হল:

[ Test Class ] Get x = None
[ x ] None

এবং যদি আমি _ ডিফল্ট = কোনটি গেটর ফাংশনে _default = 0 তে সেট করি না (যেহেতু সকল প্রাপকের একটি ডিফল্ট মান থাকা উচিত তবে এটি যা আমি দেখেছি তা থেকে সম্পত্তি মান দ্বারা গৃহীত হয় না তাই আপনি এটি এখানে সংজ্ঞায়িত করতে পারেন এবং এটি আসলে খারাপ নয় কারণ আপনি একবার ডিফল্ট সংজ্ঞায়িত করতে পারেন এবং সর্বত্র এটি ব্যবহার করতে পারেন) অর্থাৎ: def x (self, _default = 0):

[ Test Class ] Get x = 0
[ x ] 0

দ্রষ্টব্য: গটার লজিকটি এটির দ্বারা ম্যানিপুলিউটে থাকা নিশ্চিত করার জন্য মানটিকে ম্যানিপুলেট করা আছে - মুদ্রণ বিবৃতিগুলির জন্য একই ...

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

দ্রষ্টব্য: এই ফোরামে কোড আউটপুটটি ভাঙা হয়েছে - আমাকে কোডের প্রথম অংশটিতে কাজ করার জন্য স্পেস যুক্ত করতে হবে - যখন কপি / পেস্টিং আপনি সমস্ত স্পেস ট্যাবগুলিতে রূপান্তর করতে নিশ্চিত করুন .... আমি পাইথনের জন্য ট্যাবগুলি ব্যবহার করি কারণ একটি ফাইল যা 10,000 লাইন ফাইলাইজ হয় 512 কেবি থেকে 1 এমবি পর্যন্ত স্পেস এবং 100 থেকে 200KB ট্যাব সহ ফাইল আকারের জন্য একটি বৃহত পার্থক্য সমান এবং প্রক্রিয়াকরণের সময় হ্রাস হতে পারে ...

ট্যাবগুলি প্রতি ব্যবহারকারীর জন্যও সমন্বয় করা যেতে পারে - তাই যদি আপনি ২ টি স্পেস প্রস্থ, 4, 8 বা আপনি যা করতে পারেন তা পছন্দ করেন তবে এটি চোখের দৃষ্টিশক্তি ঘাটতি সহ ডেভেলপারদের জন্য চিন্তাশীল।

দ্রষ্টব্য: ফোরাম সফ্টওয়্যারের একটি বাগের কারণে শ্রেণিতে সংজ্ঞায়িত সমস্ত ক্রিয়াকলাপ সঠিকভাবে ইন্ডেন্ট করা হয় না - যদি আপনি অনুলিপি / পেস্ট করেন তবে এটি ইন্ডেন্ট করুন


নিচে থেকে নেওয়া কোডটি @property করার সময় @property কীভাবে সাহায্য করতে পারে তার আরেকটি উদাহরণ নীচে দেওয়া here (আমি কেবল নীচে এটি সংক্ষিপ্ত করে দেখি):

আপনি এই মত একটি বর্গ তৈরি কল্পনা করুন:

class Money:
    def __init__(self, dollars, cents):
        self.dollars = dollars
        self.cents = cents

এবং একজন ব্যবহারকারী এই ক্লাসের উপর নির্ভর করে লাইব্রেরি তৈরি করে যেখানে সে / সে ব্যবহার করে

money = Money(27, 12)

print("I have {} dollar and {} cents.".format(money.dollars, money.cents))
# prints I have 27 dollar and 12 cents.

এখন ধরুন আপনি আপনার Money ক্লাস পরিবর্তন করতে এবং dollars এবং cents বৈশিষ্ট্যগুলি পরিত্রাণ পেতে সিদ্ধান্ত নিচ্ছেন তবে এর পরিবর্তে শুধুমাত্র মোট সেন্টের ট্র্যাক করার সিদ্ধান্ত নিন:

class Money:
    def __init__(self, dollars, cents):
        self.total_cents = dollars * 100 + cents

উপরের উল্লিখিত ব্যবহারকারী এখন তার লাইব্রেরি চালানোর আগে চেষ্টা করে

money = Money(27, 12)

print("I have {} dollar and {} cents.".format(money.dollars, money.cents))

এটি একটি ত্রুটি ফলে হবে

গুণমান ত্রুটি: 'অর্থ' বস্তুর কোন বৈশিষ্ট্য নেই 'ডলার'

এর মানে হল যে এখন যারা আপনার আসল Money ক্লাসে নির্ভর করে তাদের কোডের সমস্ত লাইন পরিবর্তন করতে হবে যেখানে dollars এবং cents ব্যবহার করা হয় যা খুব বেদনাদায়ক হতে পারে ... সুতরাং, এটিকে কীভাবে এড়ানো যায়? @property ব্যবহার করে!

যে কিভাবে:

class Money:
    def __init__(self, dollars, cents):
        self.total_cents = dollars * 100 + cents

    # Getter and setter for dollars...
    @property
    def dollars(self):
        return self.total_cents // 100

    @dollars.setter
    def dollars(self, new_dollars):
        self.total_cents = 100 * new_dollars + self.cents

    # And the getter and setter for cents.
    @property
    def cents(self):
        return self.total_cents % 100

    @cents.setter
    def cents(self, new_cents):
        self.total_cents = 100 * self.dollars + new_cents

যখন আমরা এখন আমাদের লাইব্রেরি থেকে কল

money = Money(27, 12)

print("I have {} dollar and {} cents.".format(money.dollars, money.cents))
# prints I have 27 dollar and 12 cents.

এটি প্রত্যাশিত হিসাবে কাজ করবে এবং আমাদের লাইব্রেরিতে কোডের একক লাইন পরিবর্তন করতে হবে না! প্রকৃতপক্ষে, আমাদের জানাতে হবে না যে লাইব্রেরি আমরা পরিবর্তিত উপর নির্ভর করি।

এছাড়াও setter জরিমানা কাজ করে:

money.dollars += 2
print("I have {} dollar and {} cents.".format(money.dollars, money.cents))
# prints I have 29 dollar and 12 cents.

money.cents += 10
print("I have {} dollar and {} cents.".format(money.dollars, money.cents))
# prints I have 29 dollar and 22 cents.

documentation এটি শুধুমাত্র পাঠযোগ্য বৈশিষ্ট্য তৈরির জন্য একটি শর্টকাট। সুতরাং

@property
def x(self):
    return self._x

সমতুল্য

def getx(self):
    return self._x
x = property(getx)

@property কিভাবে @property যেতে পারে তার একটি সংক্ষিপ্ত উদাহরণ এখানে দেওয়া হল:

class Thing:
    def __init__(self, my_word):
        self._word = my_word 
    @property
    def word(self):
        return self._word

>>> print( Thing('ok').word )
'ok'

অন্যথায় word একটি সম্পত্তি পরিবর্তে একটি পদ্ধতি অবশেষ।

class Thing:
    def __init__(self, my_word):
        self._word = my_word
    def word(self):
        return self._word

>>> print( Thing('ok').word() )
'ok'




python-internals