পাইথন স্ট্যান্ডার্ড লিবের সাজসজ্জাগুলি (@ নির্দিষ্টভাবে নিযুক্ত)


127

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

অতিরিক্ত প্রশ্ন: স্ট্যান্ডার্ড লাইব্রেরিতে স্ট্যান্ডার্ড ডেকোরেটর কি আদৌ আছে?


13
এখন সেখানে একটি হল থামিয়ে দেওয়া প্যাকেজ
মিউয়ন

11
আমি এটি করার উপায়গুলি বুঝতে পেরেছি, তবে কেন এটি
স্টাড লাইব

4
কেন এটি প্রায়শই ঘটে থাকে যে প্রশ্নগুলি কয়েক ডজন উত্তর পেয়ে যায় যা এমনকি প্রশ্নের উত্তর দেওয়ার চেষ্টা করে না এবং "আমি রেসিপি সম্পর্কে সচেতন" এর মতো বিষয়গুলিকে সক্রিয়ভাবে উপেক্ষা করে? এটা পাগল!
ক্যাটসকুল

1
@ ক্যাটস্কুল জাল ইন্টারনেট পয়েন্টের কারণে
স্টেফানো বোরিনি

1
আপনি অবহেলা গ্রন্থাগারটি ব্যবহার করতে পারেন ।
লরেন্ট LAPORTE

উত্তর:


59

এখানে কিছু স্নিপেট রয়েছে, যা লিয়ানড্রোর দ্বারা উদ্ধৃত হয়েছে:

import warnings
import functools

def deprecated(func):
    """This is a decorator which can be used to mark functions
    as deprecated. It will result in a warning being emitted
    when the function is used."""
    @functools.wraps(func)
    def new_func(*args, **kwargs):
        warnings.simplefilter('always', DeprecationWarning)  # turn off filter
        warnings.warn("Call to deprecated function {}.".format(func.__name__),
                      category=DeprecationWarning,
                      stacklevel=2)
        warnings.simplefilter('default', DeprecationWarning)  # reset filter
        return func(*args, **kwargs)
    return new_func

# Examples

@deprecated
def some_old_function(x, y):
    return x + y

class SomeClass:
    @deprecated
    def some_old_method(self, x, y):
        return x + y

কারণ কিছু দোভাষীর মধ্যে প্রথম সমাধান উন্মুক্ত (ফিল্টার হ্যান্ডলিং ছাড়াই) একটি সতর্কতা দমন করতে পারে।


14
functools.wrapsনাম এবং দস্তাবেজের মতো সেট করার চেয়ে কেন ব্যবহার করবেন না?
ম্যাক্সিমিলিয়ান

1
@ ম্যাক্সিমিলিয়ান: এটি যুক্ত করার জন্য সম্পাদনা করা হয়েছে, ভবিষ্যতে এই কোডটির অনুলিপি পোস্টকারীদের এটি অন্যায় করতে থেকে বাঁচাতে
এরিক

17
আমি পার্শ্ব প্রতিক্রিয়া পছন্দ করি না (ফিল্টারটি চালু / বন্ধ)। এটি সিদ্ধান্ত নেওয়ার জন্য এটি সাজসজ্জার কাজ নয়।
কেনটজো

1
ফিল্টারটি চালু এবং বন্ধ করার ফলে বাগগুলি
জারিত

4
প্রকৃত প্রশ্নের উত্তর দেয় না।
ক্যাটসকুল

44

এখানে আরও একটি সমাধান:

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

সম্পাদনা : এই কোডটি জিরোর প্রস্তাবনা ব্যবহার করে: এটি warnings.warn_explicitলাইন দ্বারা প্রতিস্থাপন করেwarnings.warn(msg, category=DeprecationWarning, stacklevel=2) , যা ফাংশন সংজ্ঞা সাইটের চেয়ে ফাংশন কল সাইটটি মুদ্রণ করে। এটি ডিবাগিংকে সহজ করে তোলে।

সম্পাদনা 2 : এই সংস্করণটি বিকাশকারীকে একটি alচ্ছিক "কারণ" বার্তা নির্দিষ্ট করার অনুমতি দেয়।

import functools
import inspect
import warnings

string_types = (type(b''), type(u''))


def deprecated(reason):
    """
    This is a decorator which can be used to mark functions
    as deprecated. It will result in a warning being emitted
    when the function is used.
    """

    if isinstance(reason, string_types):

        # The @deprecated is used with a 'reason'.
        #
        # .. code-block:: python
        #
        #    @deprecated("please, use another function")
        #    def old_function(x, y):
        #      pass

        def decorator(func1):

            if inspect.isclass(func1):
                fmt1 = "Call to deprecated class {name} ({reason})."
            else:
                fmt1 = "Call to deprecated function {name} ({reason})."

            @functools.wraps(func1)
            def new_func1(*args, **kwargs):
                warnings.simplefilter('always', DeprecationWarning)
                warnings.warn(
                    fmt1.format(name=func1.__name__, reason=reason),
                    category=DeprecationWarning,
                    stacklevel=2
                )
                warnings.simplefilter('default', DeprecationWarning)
                return func1(*args, **kwargs)

            return new_func1

        return decorator

    elif inspect.isclass(reason) or inspect.isfunction(reason):

        # The @deprecated is used without any 'reason'.
        #
        # .. code-block:: python
        #
        #    @deprecated
        #    def old_function(x, y):
        #      pass

        func2 = reason

        if inspect.isclass(func2):
            fmt2 = "Call to deprecated class {name}."
        else:
            fmt2 = "Call to deprecated function {name}."

        @functools.wraps(func2)
        def new_func2(*args, **kwargs):
            warnings.simplefilter('always', DeprecationWarning)
            warnings.warn(
                fmt2.format(name=func2.__name__),
                category=DeprecationWarning,
                stacklevel=2
            )
            warnings.simplefilter('default', DeprecationWarning)
            return func2(*args, **kwargs)

        return new_func2

    else:
        raise TypeError(repr(type(reason)))

আপনি এই ডেকরেটারটি ফাংশন , পদ্ধতি এবং ক্লাসের জন্য ব্যবহার করতে পারেন

এখানে একটি সহজ উদাহরণ:

@deprecated("use another function")
def some_old_function(x, y):
    return x + y


class SomeClass(object):
    @deprecated("use another method")
    def some_old_method(self, x, y):
        return x + y


@deprecated("use another class")
class SomeOldClass(object):
    pass


some_old_function(5, 3)
SomeClass().some_old_method(8, 9)
SomeOldClass()

তুমি পাবে:

deprecated_example.py:59: DeprecationWarning: Call to deprecated function or method some_old_function (use another function).
  some_old_function(5, 3)
deprecated_example.py:60: DeprecationWarning: Call to deprecated function or method some_old_method (use another method).
  SomeClass().some_old_method(8, 9)
deprecated_example.py:61: DeprecationWarning: Call to deprecated class SomeOldClass (use another class).
  SomeOldClass()

সম্পাদনা 3: এই সাজসজ্জারটি এখন অবজ্ঞাত লাইব্রেরির অংশ:

নতুন স্থিতিশীল রিলিজ v1.2.10 🎉


6
কাজ করে, ভাল - আমি warn_explicitলাইনটি প্রতিস্থাপন করতে পছন্দ করি warnings.warn(msg, category=DeprecationWarning, stacklevel=2)যা ফাংশন সংজ্ঞা সাইটের চেয়ে ফাংশন কল সাইট প্রিন্ট করে with এটি ডিবাগিংকে সহজ করে তোলে।
শূন্য

হ্যালো, আমি আপনার কোড স্নিপেট একটি জিপিএলভি 3-লাইসেন্সযুক্ত লাইব্রেরিতে ব্যবহার করতে চাই । আপনি কি জিপিএলভি 3 বা আরও কোনও অনুমতিপ্রাপ্ত লাইসেন্সের অধীনে আপনার কোডটি পুনরায় প্রকাশ করতে ইচ্ছুক হবেন , যাতে আমি আইনীভাবে এটি করতে পারি?
অঙ্কুরিত


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

2
প্রকৃত প্রশ্নের উত্তর দেয় না।
ক্যাটসকুল

15

মুউন যেমন পরামর্শ দিয়েছে আপনি এর deprecationজন্য প্যাকেজটি ইনস্টল করতে পারেন ।

deprecationগ্রন্থাগার একটি উপলব্ধ deprecatedপ্রসাধক এবং fail_if_not_removedআপনার পরীক্ষার জন্য প্রসাধক।

স্থাপন

pip install deprecation

ব্যবহারের উদাহরণ

import deprecation

@deprecation.deprecated(deprecated_in="1.0", removed_in="2.0",
                        current_version=__version__,
                        details="Use the bar function instead")
def foo():
    """Do some stuff"""
    return 1

সম্পূর্ণ ডকুমেন্টেশনের জন্য http://deprecation.readthedocs.io/ দেখুন ।


4
প্রকৃত প্রশ্নের উত্তর দেয় না।
ক্যাটসকুল

1
নোট PyCharm এই স্বীকৃতি দেয় না
CZ

11

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

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


3
এবং মডিউল থেকে ফাংশনটি আমদানি করা হলে আপনার অবচয়কে নির্দেশ করতে সক্ষম হওয়া উচিত । সাজসজ্জার জন্য এটি একটি সঠিক সরঞ্জাম হবে।
জানুস লেনার

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

8

আপনি একটি ইউটিস ফাইল তৈরি করতে পারেন

import warnings

def deprecated(message):
  def deprecated_decorator(func):
      def deprecated_func(*args, **kwargs):
          warnings.warn("{} is a deprecated function. {}".format(func.__name__, message),
                        category=DeprecationWarning,
                        stacklevel=2)
          warnings.simplefilter('default', DeprecationWarning)
          return func(*args, **kwargs)
      return deprecated_func
  return deprecated_decorator

এবং তারপরে অবনতি সজ্জা আমদানি করুন:

from .utils import deprecated

@deprecated("Use method yyy instead")
def some_method()"
 pass

ধন্যবাদ, আমি ব্যবহারকারীকে কেবল হ্রাসের বার্তা না দেখিয়ে সঠিক জায়গায় প্রেরণ করতে এটি ব্যবহার করছি!
জার্মান অ্যাটানাসিও

3
প্রকৃত প্রশ্নের উত্তর দেয় না।
ক্যাটসকুল

2

আপডেট: আমার মনে হয় আরও ভাল, যখন আমরা কেবল প্রথমবারের জন্য অবজ্ঞাত ওয়ার্নিং দেখি প্রতিটি কোড লাইনের দেখি এবং যখন আমরা কিছু বার্তা পাঠাতে পারি:

import inspect
import traceback
import warnings
import functools

import time


def deprecated(message: str = ''):
    """
    This is a decorator which can be used to mark functions
    as deprecated. It will result in a warning being emitted
    when the function is used first time and filter is set for show DeprecationWarning.
    """
    def decorator_wrapper(func):
        @functools.wraps(func)
        def function_wrapper(*args, **kwargs):
            current_call_source = '|'.join(traceback.format_stack(inspect.currentframe()))
            if current_call_source not in function_wrapper.last_call_source:
                warnings.warn("Function {} is now deprecated! {}".format(func.__name__, message),
                              category=DeprecationWarning, stacklevel=2)
                function_wrapper.last_call_source.add(current_call_source)

            return func(*args, **kwargs)

        function_wrapper.last_call_source = set()

        return function_wrapper
    return decorator_wrapper


@deprecated('You must use my_func2!')
def my_func():
    time.sleep(.1)
    print('aaa')
    time.sleep(.1)


def my_func2():
    print('bbb')


warnings.simplefilter('always', DeprecationWarning)  # turn off filter
print('before cycle')
for i in range(5):
    my_func()
print('after cycle')
my_func()
my_func()
my_func()

ফলাফল:

before cycle
C:/Users/adr-0/OneDrive/Projects/Python/test/unit1.py:45: DeprecationWarning: Function my_func is now deprecated! You must use my_func2!
aaa
aaa
aaa
aaa
aaa
after cycle
C:/Users/adr-0/OneDrive/Projects/Python/test/unit1.py:47: DeprecationWarning: Function my_func is now deprecated! You must use my_func2!
aaa
C:/Users/adr-0/OneDrive/Projects/Python/test/unit1.py:48: DeprecationWarning: Function my_func is now deprecated! You must use my_func2!
aaa
C:/Users/adr-0/OneDrive/Projects/Python/test/unit1.py:49: DeprecationWarning: Function my_func is now deprecated! You must use my_func2!
aaa

Process finished with exit code 0

আমরা কেবল সতর্কতার পথে ক্লিক করতে পারি এবং পাইচার্মের লাইনে যেতে পারি।


2
প্রকৃত প্রশ্নের উত্তর দেয় না।
ক্যাটসকুল

0

স্টিভেন ভ্যাসেল্লারোর এই উত্তরকে বাড়িয়ে তোলা :

আপনি যদি অ্যানাকোন্ডা ব্যবহার করেন তবে প্রথমে deprecationপ্যাকেজ ইনস্টল করুন :

conda install -c conda-forge deprecation 

তারপরে ফাইলটির উপরের অংশে নিম্নলিখিতটি পেস্ট করুন

import deprecation

@deprecation.deprecated(deprecated_in="1.0", removed_in="2.0",
                    current_version=__version__,
                    details="Use the bar function instead")
def foo():
    """Do some stuff"""
    return 1

সম্পূর্ণ ডকুমেন্টেশনের জন্য http://deprecation.readthedocs.io/ দেখুন ।


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