استخدام المتغيرات لأسماء الفئات في بايثون؟

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

  •  03-07-2019
  •  | 
  •  

سؤال

أريد أن أعرف كيفية استخدام المتغيرات للكائنات وأسماء الوظائف في بايثون.في PHP، يمكنك القيام بذلك:

$className = "MyClass";

$newObject = new $className();

كيف تفعل هذا النوع من الأشياء في بايثون؟أم أنني لا أقدر تمامًا بعض الاختلاف الأساسي مع بايثون، وإذا كان الأمر كذلك، فما هو؟

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

المحلول

في بيثون،

className = MyClass
newObject = className()

والسطر الأول يجعل className متغير تشير إلى نفس الشيء كما MyClass. ثم يدعو السطر التالي منشئ MyClass من خلال المتغير className.

ووكمثال ملموس:

>>> className = list
>>> newObject = className()
>>> newObject
[]

و(في بيثون، list هو منشئ للفئة list).

والفرق هو أن في PHP، التي تمثل اسم الفئة التي تريد الرجوع إلى كسلسلة، بينما في بيثون يمكنك الرجوع إلى نفس الفئة مباشرة. إذا كنت <م> يجب استخدام سلسلة (على سبيل المثال إذا تم إنشاء اسم الفئة حيوي)، فإنك سوف تحتاج إلى استخدام تقنيات أخرى.

نصائح أخرى

وعلى افتراض أن some_module لديها فئة المسمى "CLASS_NAME":

import some_module
klass = getattr(some_module, "class_name")
some_object = klass()

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

واحد وسيلة أخرى (على افتراض أننا ما زلنا تستخدم "CLASS_NAME"):

class_lookup = { 'class_name' : class_name }
some_object = class_lookup['class_name']()  #call the object once we've pulled it out of the dict

والأسلوب الأخير هو على الأرجح الطريقة الأكثر أمانا للقيام بذلك، لذلك ربما ما عليك أن تستخدم إذا كان ذلك ممكنا.

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

>>> class_name = 'MyClass'
>>> klass = type(class_name, (object,), {'msg': 'foobarbaz'})

<class '__main__.MyClass'>

>>> inst = klass()
>>> inst.msg
foobarbaz
  • ومع ذلك، لاحظ أن هذا لا يؤدي إلى "إنشاء مثيل" للكائن (على سبيل المثال.لا يستدعي المنشئين وما إلى ذلك.يقوم بإنشاء فئة جديدة (!) بنفس الاسم.

إذا كان لديك هذا:

class MyClass:
    def __init__(self):
        print "MyClass"

وبعد ذلك يمكنك عادة القيام بذلك:

>>> x = MyClass()
MyClass

ولكن هل يمكن أيضا القيام بذلك، وهو ما أعتقد كنت طالبا:

>>> a = "MyClass"
>>> y = eval(a)()
MyClass

ولكن، نكون حذرين جدا حول حيث تحصل على سلسلة من استخدام "وحدة التقييم ()" على - إذا لم تأتي من المستخدم، وأنت خلق أساسا ثغرة أمنية هائلة

تحديث: استخدام type() كما هو مبين في الجواب coleifer هو أعلى بكثير من هذا الحل

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