ما هو pythonic طريقة لتجنب المعلمات الافتراضية التي تكون فارغة القوائم ؟

StackOverflow https://stackoverflow.com/questions/366422

  •  21-08-2019
  •  | 
  •  

سؤال

في بعض الأحيان يبدو من الطبيعي أن يكون المعلمة الافتراضية والتي هي قائمة فارغة.بعد بيثون يعطي سلوك غير متوقع في هذه الحالات.

على سبيل المثال إذا كان لدي وظيفة:

def my_func(working_list = []):
    working_list.append("a")
    print(working_list)

المرة الأولى ويسمى الافتراضي و يدعو بعد ذلك سيتم تحديث القائمة الحالية (مع واحد "و" كل مكالمة) وطباعة نسخة محدثة.

فما هو pythonic طريقة للحصول على السلوك الرغبة في (قائمة جديدة على كل مكالمة)?

هل كانت مفيدة؟

المحلول

def my_func(working_list=None):
    if working_list is None: 
        working_list = []

    working_list.append("a")
    print(working_list)

ومستندات نقول يجب عليك استخدام None كافتراض وصراحة لذلك في الجسم وظيفة.

نصائح أخرى

القائمة إجابات قدمت بالفعل المباشر الحلول كما طلبت.ومع ذلك, لأن هذا شرك شائع جدا جديدة الثعبان المبرمجين يستحق لإضافة تفسير لماذا الثعبان يتصرف بهذه الطريقة ، وهو لطيف تلخيصها في "متطفلين دليل الثعبان"كما "قابلة للتغيير الافتراضي الحجج": http://docs.python-guide.org/en/latest/writing/gotchas/

اقتباس:"بايثون الافتراضي الحجج يتم تقييم مرة واحدة عندما يتم تعريف الدالة ، وليس في كل مرة يتم استدعاء الدالة (كما في القول روبي).هذا يعني أنه إذا كنت تستخدم قابلة للتغيير الافتراضي حجة وتتحور ذلك ، سوف و تحور هذا الكائن لجميع المكالمات في المستقبل إلى وظيفة كما"

نموذج التعليمات البرمجية لتنفيذ ذلك:

def foo(element, to=None):
    if to is None:
        to = []
    to.append(element)
    return to

لا يهم في هذه الحالة، ولكن يمكنك استخدام هوية الكائن لاختبار بلا:

if working_list is None: working_list = []

ويمكنك أيضا الاستفادة من كيفية تشغيل منطقية أو محددة في بيثون:

working_list = working_list or []

وعلى الرغم من أن هذا سوف تتصرف بشكل غير متوقع إذا كان المتصل يعطيك قائمة فارغة (التي تعتبر كاذبة ع) كما working_list وتتوقع وظيفة لتعديل قائمة أعطاها.

إذا كان القصد من الوظيفة تعديل المعلمة كما مر working_list, انظر HenryR الجواب (=لا شيء تحقق أيا من الداخل).

ولكن إذا كنت لا تنوي التحور الحجة ، مجرد استخدامه بمثابة نقطة انطلاق القائمة ، يمكنك ببساطة نسخ:

def myFunc(starting_list = []):
    starting_list = list(starting_list)
    starting_list.append("a")
    print starting_list

(أو في هذه الحالة بسيطة فقط print starting_list + ["a"] لكن أعتقد أنه كان مجرد لعبة سبيل المثال)

في عام ، تحور حججك هو أسلوب سيئة في بيثون.فقط الوظائف التي من المتوقع تماما أن يتحور كائن هي أساليب الكائن.حتى أنه من النادر جدا أن يتحول اختياري الحجة — هو أحد الآثار الجانبية يحدث ذلك فقط في بعض المكالمات حقا أفضل واجهة ؟

  • إذا كنت تفعل ذلك من ج العادة "إخراج حجج" هذا لا لزوم لها تماما - يمكنك دائما العودة متعددة القيم tuple.

  • إذا كان يمكنك القيام بذلك بكفاءة بناء قائمة طويلة من النتائج دون بناء المتوسطة قوائم النظر في كتابة أنها مولد باستخدام result_list.extend(myFunc()) عندما يتم استدعاء.هذه الطريقة الاتفاقيات الدعوة لا تزال نظيفة جدا.

نمط واحد حيث تحور اختياري arg هو في كثير من الأحيان القيام به هو مخفي "مذكرة" arg في وظائف العودية:

def depth_first_walk_graph(graph, node, _visited=None):
    if _visited is None:
        _visited = set()  # create memo once in top-level call

    if node in _visited:
        return
    _visited.add(node)
    for neighbour in graph[node]:
        depth_first_walk_graph(graph, neighbour, _visited)

وأنا قد يكون خارج الموضوع، ولكن تذكر أنه إذا كنت ترغب فقط في تمرير عدد متغير من الوسائط، والطريقة pythonic هي لتمرير *args الصفوف (tuple) أو **kargs القاموس. هذه هي اختيارية، وهي أفضل من myFunc([1, 2, 3]) بناء الجملة.

إذا كنت تريد تمرير الصفوف (tuple):

def myFunc(arg1, *args):
  print args
  w = []
  w += args
  print w
>>>myFunc(1, 2, 3, 4, 5, 6, 7)
(2, 3, 4, 5, 6, 7)
[2, 3, 4, 5, 6, 7]

إذا كنت تريد تمرير القاموس:

def myFunc(arg1, **kargs):
   print kargs
>>>myFunc(1, option1=2, option2=3)
{'option2' : 2, 'option1' : 3}

وكانت هناك بالفعل جيدة والإجابات الصحيحة المقدمة. أردت فقط أن يعطي تركيب آخر لكتابة ما تريد القيام به الذي أجد أكثر جمالا عند مثلا تريد إنشاء فئة مع القوائم فارغة الافتراضي:

class Node(object):
    def __init__(self, _id, val, parents=None, children=None):
        self.id = _id
        self.val = val
        self.parents = parents if parents is not None else []
        self.children = children if children is not None else []

وهذه قصاصة يجعل من استخدام بناء الجملة مشغل آخر إذا. أنا أحب ذلك خصوصا لأنها أنيق قليلا أونيلينير دون كولون، وما إلى ذلك تشارك ويقرأ تقريبا مثل الجملة الإنجليزية العادية. :)

في حالتك يمكن أن تكتب

def myFunc(working_list=None):
    working_list = [] if working_list is None else working_list
    working_list.append("a")
    print working_list

وأخذت UCSC الملحق فئة Python for programmer

ما هو صحيح من: الجبهة الوطنية صفر (بيانات = []):

<اقتباس فقرة>   

وأ) هو فكرة جيدة بحيث تبدأ قوائم البيانات الخاصة بك فارغة مع كل مكالمة.

     

وب) هو فكرة جيدة حتى يتسنى لجميع المكالمات إلى الدالة التي لا توفر أي حجج على المكالمة سوف تحصل على قائمة فارغة إلى بيانات.

     

وج) هي فكرة معقولة طالما أن البيانات الخاصة بك قائمة السلاسل.

     

ود) هو فكرة سيئة لأن الافتراضي [] سوف تتراكم البيانات والافتراضي [] سوف تتغير مع المكالمات اللاحقة.

الجواب:

<اقتباس فقرة>   

ود) هو فكرة سيئة لأن الافتراضي [] سوف تتراكم البيانات والافتراضي [] سوف تتغير مع المكالمات اللاحقة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top