Pertanyaan Secara dinamis membuat kelas dari file dengan Python


Saya telah melihat pertanyaan "Secara dinamis membuat kelas" yang dijawab dengan mengatakan, "gunakan fungsi jenis ()". Saya yakin saya akan harus pada titik tertentu tetapi benar tahu saya tidak mengerti. Tetapi dari apa yang saya lihat Anda harus sudah mengetahui sesuatu tentang kelas, seperti nama.

Apa yang saya coba lakukan adalah mengurai jenis file idl dan dari yang membuat kelas yang akan memiliki metode dan atribut. Jadi saya TIDAK memiliki pengetahuan di depan apa nama kelas, fungsi, argumen atau apa pun akan sampai saya mem-parse string.

Ada ide?


5
2018-05-11 17:17


asal


Jawaban:


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

Ini agak sulit untuk Google, tetapi Anda dapat mencari python type(name, bases, dict) function examples mendapatkan:

http://www.voidspace.org.uk/python/articles/metaclasses.shtml

Kutipan dari atas, yang sampai ke inti pertanyaan Anda:


Berikut ini pada dasarnya sama:

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

def printX(self):
    print self.x

Test = type('Test', (object,), {'__init__': __init__, 'printX': printX})

dan:

class Test(object):
    def __init__(self, x):
        self.x = x

    def printX(self):
        print self.x

Ada dua cara untuk membuat fungsi dengan cepat yang dapat saya pikirkan. Cara yang biasanya buruk adalah menulis kode dan membaliknya (meskipun dilakukan dengan benar, ini dapat sangat meningkatkan kinerja). Cara yang waras adalah mengimplementasikan fungsi yang menafsirkan IDL Anda. Ini disebut fungsi tingkat tinggi: http://effbot.org/pyfaq/how-do-you-make-a-higher-order-function-in-python.htm

Contoh apa yang akan Anda tulis, jika Anda tidak dapat menemukan juru bahasa untuk IDL Anda (jika IDL khusus) adalah sesuatu seperti tautan di atas, seperti:

def makeMethod(idlCode):
    syntax = MyIDL.parse(idlCode)

    def newMethod(*args, **kw):
        if syntax.statementType == MyIDL.IF_STATEMENT:
            if secureLookup(mySyntaxTree.IF):
               return secureLookup(args[0]) 
            else:
               return secureLookup(args[1])
        ...

    return (syntax.methodName, newMethod)

Ada banyak cara yang lebih elegan untuk memperluas metode ini, jika Anda mengatur pemetaan antara konstruk IDL Anda dan sintaks * args dan ** kw, tetapi ini memberi Anda fleksibilitas dan merupakan cara yang paling mudah dan mendasar yang dapat saya lakukan. pikirkan.

Maka Anda akan lulus:

class DynamicIdlClass(object):
    ...

for idlObject in idlCode:
    methods = dict(makeMethod(clause) for clause in idlObject.clauses})
    methods['__init__'] = makeInitMethod(idlObject.initClause)
    idlObject = type('Test', (DynamicIdlClass,), methods)

    yield idlObject  # or idlObjectsList.push(idlObject), etc.

14
2018-05-11 17:25



Daripada memikirkan ini sebagai 'bagaimana cara membuat kelas secara dinamis', menganggapnya sebagai kesempatan untuk menggunakan kemampuan metaprogramming dari Python sebagai gantinya.

Tempat pertama yang saya cari adalah sumber pustaka standar untuk xmlrpclib - lihat secara khusus bagaimana penggunaannya __getattr__ untuk menangani metode panggilan yang tidak ada dengan cepat.

Saya tahu bahwa saya tidak benar-benar mengerti mengapa mereka menyebut Python bahasa yang dinamis sampai saya sepenuhnya memahami kemungkinan-kemungkinan itu.


1
2018-05-11 17:53



Pada proyek kami, kami membuat objek yang memaparkan metode konkrit yang memiliki kemampuan untuk menambahkan atribut callable. Kami mem-parse banyak file yaml untuk skema dan merakit objek-objek ini secara dinamis.

Sesuatu yang mirip dengan

def add_method(name, callable):
    setattr(self,name,callable)

Tapi ini adalah contoh yang sangat naif tetapi Anda mendapatkan ide itu. Skema disimpan di dalam setiap kelas dinamis di bawah sesuatu seperti __schema yang merupakan kamus berisi prototipe kwarg dan dokumentasi.

Untuk callables yang sebenarnya membuat kerangka seperti

def skel(self, *args, **kwargs):
    if '_schema' in kwargs:
        parse_yml, add control statements
    handle args and kwargs based on schema

some_instance.add_method('blah',skel)

Sekali lagi, ini adalah contoh yang sangat naif dan tidak mencakup sebagian besar masalah dan kasus tepi yang muncul ketika bekerja dengan jenis masalah ini. Ini juga merupakan salah satu dari beberapa metode untuk menemukan solusi.

Contoh:

IonObject

Generator Model Obyek


1
2018-05-11 17:28