C-όπως δομές στην Python

ψήφοι
304

Είναι ένας τρόπος για να καθορίσει εύκολα ένα C-όπως δομή σε Python εκεί; Είμαι κουρασμένος από τη σύνταξη πράγματα όπως:

class MyStruct():
    def __init__(self, field1, field2, field3):
        self.field1 = field1
        self.field2 = field2
        self.field3 = field3
Δημοσιεύθηκε 30/08/2008 στις 13:33
πηγή χρήστη
Σε άλλες γλώσσες...                            


23 απαντήσεις

ψήφοι
52

Τι θα λέγατε για ένα λεξικό;

Κάτι σαν αυτό:

myStruct = {'field1': 'some val', 'field2': 'some val'}

Στη συνέχεια, μπορείτε να χρησιμοποιήσετε αυτό για να χειραγωγήσουν τις τιμές:

print myStruct['field1']
myStruct['field2'] = 'some other values'

Και οι τιμές δεν πρέπει να είναι χορδές. Μπορεί να είναι λίγο πολύ οποιοδήποτε άλλο αντικείμενο.

Απαντήθηκε 30/08/2008 στις 13:35
πηγή χρήστη

ψήφοι
91

Μπορείτε να χρησιμοποιήσετε μια πλειάδα για πολλά πράγματα, όπου θα πρέπει να χρησιμοποιήσετε ένα struct σε C (κάτι σαν x, y συντεταγμένες ή τα χρώματα RGB, για παράδειγμα).

Για ό, τι άλλο μπορείτε να χρησιμοποιήσετε λεξικό, ή μια κατηγορία βοηθητικό πρόγραμμα, όπως αυτό :

>>> class Bunch:
...     def __init__(self, **kwds):
...         self.__dict__.update(kwds)
...
>>> mystruct = Bunch(field1=value1, field2=value2)

Νομίζω ότι το «οριστικό» συζήτηση είναι εδώ , στη δημοσιευμένη έκδοση της Python Cookbook.

Απαντήθηκε 30/08/2008 στις 13:38
πηγή χρήστη

ψήφοι
289

Χρησιμοποιήστε ένα που ονομάζεται πλειάδα , η οποία προστέθηκε στην ενότητα συλλογές στην πρότυπη βιβλιοθήκη στην Python 2.6. Είναι επίσης δυνατή η χρήση Raymond Hettinger το όνομά πλειάδα συνταγή, αν πρέπει να υποστηρίζουν την Python 2.4.

Είναι ωραίο για τις βασικές παράδειγμά σας, αλλά και καλύπτει μια δέσμη των περιπτώσεων ακμής μπορεί να τρέξει σε μεταγενέστερο επίσης. κομμάτι σας παραπάνω θα πρέπει να γραφτεί ως εξής:

from collections import namedtuple
MyStruct = namedtuple("MyStruct", "field1 field2 field3")

Ο τύπος που μόλις δημιουργήθηκε μπορεί να χρησιμοποιηθεί σαν αυτό:

m = MyStruct("foo", "bar", "baz")

Μπορείτε επίσης να χρησιμοποιήσετε το όνομα επιχειρήματα:

m = MyStruct(field1="foo", field2="bar", field3="baz")
Απαντήθηκε 30/08/2008 στις 14:18
πηγή χρήστη

ψήφοι
23

DF: αυτό είναι αρκετά δροσερό ... Δεν ήξερα ότι θα μπορούσα να έχουν πρόσβαση τα πεδία σε μια τάξη χρησιμοποιώντας dict.

Σημειώστε: οι καταστάσεις που Μακάρι να είχα αυτό ακριβώς είναι όταν θέλω μια πλειάδα αλλά τίποτα το «βαρύ» σαν ένα λεξικό.

Μπορείτε να αποκτήσετε πρόσβαση στα πεδία της τάξης χρησιμοποιώντας ένα λεξικό, επειδή τα πεδία μιας κατηγορίας, οι μέθοδοι και όλες τις ιδιότητές της, αποθηκεύονται στο εσωτερικό χρησιμοποιώντας DICTS (τουλάχιστον σε CPython).

... Που μας οδηγεί στο δεύτερο σχόλιό σας. Πιστεύοντας ότι η Python DICTS είναι «βαριά» είναι ένα εξαιρετικά μη-pythonistic έννοια. Και διαβάζοντας τα σχόλια αυτά σκοτώνει Python Ζεν μου. Αυτό δεν είναι καλό.

Βλέπετε, όταν δηλώνετε μια τάξη που είναι στην πραγματικότητα δημιουργώντας ένα όμορφο συγκρότημα περιτύλιγμα γύρω από ένα λεξικό - έτσι, αν μη τι άλλο, πρόκειται να προσθέσετε περισσότερο γενικά ό, τι με τη χρήση ενός απλού λεξικού. Μια εναέρια οποία, από τον τρόπο, δεν έχει νόημα σε κάθε περίπτωση. Αν εργάζεστε σε απόδοση κρίσιμων εφαρμογών, χρησιμοποιήστε το C ή κάτι τέτοιο.

Απαντήθηκε 30/08/2008 στις 14:20
πηγή χρήστη

ψήφοι
14

Μπορείτε επίσης να περάσετε τις παραμέτρους εκκίνησης για να τις μεταβλητές παράδειγμα από τη θέση

# Abstract struct class       
class Struct:
    def __init__ (self, *argv, **argd):
        if len(argd):
            # Update by dictionary
            self.__dict__.update (argd)
        else:
            # Update by position
            attrs = filter (lambda x: x[0:2] != "__", dir(self))
            for n in range(len(argv)):
                setattr(self, attrs[n], argv[n])

# Specific class
class Point3dStruct (Struct):
    x = 0
    y = 0
    z = 0

pt1 = Point3dStruct()
pt1.x = 10

print pt1.x
print "-"*10

pt2 = Point3dStruct(5, 6)

print pt2.x, pt2.y
print "-"*10

pt3 = Point3dStruct (x=1, y=2, z=3)
print pt3.x, pt3.y, pt3.z
print "-"*10
Απαντήθηκε 30/08/2008 στις 14:53
πηγή χρήστη

ψήφοι
75

Ίσως ψάχνετε για Δομές χωρίς κατασκευαστών:

class Sample:
  name = ''
  average = 0.0
  values = None # list cannot be initialized here!


s1 = Sample()
s1.name = "sample 1"
s1.values = []
s1.values.append(1)
s1.values.append(2)
s1.values.append(3)

s2 = Sample()
s2.name = "sample 2"
s2.values = []
s2.values.append(4)

for v in s1.values:   # prints 1,2,3 --> OK.
  print v
print "***"
for v in s2.values:   # prints 4 --> OK.
  print v
Απαντήθηκε 21/09/2010 στις 14:15
πηγή χρήστη

ψήφοι
9

Κάθε φορά που χρειάζεται ένα «στιγμιαίο αντικείμενο δεδομένων που συμπεριφέρεται και σαν ένα λεξικό» (Ι δεν ! Σκεφτώ C Δομές), νομίζω ότι από αυτό το χαριτωμένο hack:

class Map(dict):
    def __init__(self, **kwargs):
        super(Map, self).__init__(**kwargs)
        self.__dict__ = self

Τώρα το μόνο που μπορούμε να πούμε:

struct = Map(field1='foo', field2='bar', field3=42)

self.assertEquals('bar', struct.field2)
self.assertEquals(42, struct['field3'])

Τέλεια βολικό για εκείνους τους χρόνους όταν χρειάζεστε μια «σακούλα δεδομένα που δεν είναι μια τάξη», και όταν namedtuples είναι ακατανόητο ...

Απαντήθηκε 13/09/2013 στις 16:40
πηγή χρήστη

ψήφοι
6

Μπορείτε να αποκτήσετε πρόσβαση struct C-Style σε python στο ακόλουθο τρόπο.

class cstruct:
    var_i = 0
    var_f = 0.0
    var_str = ""

αν απλά θέλετε να χρησιμοποιήσετε αντικείμενο της cstruct

obj = cstruct()
obj.var_i = 50
obj.var_f = 50.00
obj.var_str = "fifty"
print "cstruct: obj i=%d f=%f s=%s" %(obj.var_i, obj.var_f, obj.var_str)

αν θέλετε να δημιουργήσετε μια σειρά από αντικείμενα της cstruct

obj_array = [cstruct() for i in range(10)]
obj_array[0].var_i = 10
obj_array[0].var_f = 10.00
obj_array[0].var_str = "ten"

#go ahead and fill rest of array instaces of struct

#print all the value
for i in range(10):
    print "cstruct: obj_array i=%d f=%f s=%s" %(obj_array[i].var_i, obj_array[i].var_f, obj_array[i].var_str)

Σημείωση: αντί για το όνομα «cstruct», παρακαλούμε να χρησιμοποιήσετε το όνομα struct σας αντί var_i, var_f, var_str, παρακαλούμε να ορίσετε μεταβλητές μέλους δομή σας.

Απαντήθηκε 09/11/2014 στις 05:37
πηγή χρήστη

ψήφοι
3

Αυτό θα μπορούσε να είναι λίγο αργά, αλλά έκανα μια λύση με τη χρήση Python Meta-Μαθήματα (έκδοση διακοσμητής κάτω από πάρα πολύ).

Όταν __init__καλείται κατά το χρόνο εκτέλεσης, το αρπάζει κάθε ένα από τα επιχειρήματα και την αξία τους και να τους αναθέτει ως παράδειγμα μεταβλητές στην τάξη σας. Με αυτό τον τρόπο μπορείτε να κάνετε ένα struct που μοιάζει με τάξη, χωρίς να χρειάζεται να εκχωρήσετε κάθε τιμή χειροκίνητα.

παράδειγμα μου δεν έχει τον έλεγχο, ώστε να είναι ευκολότερο να ακολουθήσετε λάθος.

class MyStruct(type):
    def __call__(cls, *args, **kwargs):
        names = cls.__init__.func_code.co_varnames[1:]

        self = type.__call__(cls, *args, **kwargs)

        for name, value in zip(names, args):
            setattr(self , name, value)

        for name, value in kwargs.iteritems():
            setattr(self , name, value)
        return self 

Εδώ είναι σε δράση.

>>> class MyClass(object):
    __metaclass__ = MyStruct
    def __init__(self, a, b, c):
        pass


>>> my_instance = MyClass(1, 2, 3)
>>> my_instance.a
1
>>> 

I δημοσιεύτηκε στο reddit και / u / matchu δημοσίευσε μια έκδοση διακοσμητή που είναι καθαρότερα. Θα ήθελα να σας ενθαρρύνω να το χρησιμοποιήσετε αν θέλετε να επεκτείνετε την έκδοση μετακλάση.

>>> def init_all_args(fn):
    @wraps(fn)
    def wrapped_init(self, *args, **kwargs):
        names = fn.func_code.co_varnames[1:]

        for name, value in zip(names, args):
            setattr(self, name, value)

        for name, value in kwargs.iteritems():
            setattr(self, name, value)

    return wrapped_init

>>> class Test(object):
    @init_all_args
    def __init__(self, a, b):
        pass


>>> a = Test(1, 2)
>>> a.a
1
>>> 
Απαντήθηκε 23/03/2015 στις 12:32
πηγή χρήστη

ψήφοι
12

Μπορείτε να υποκατηγορία τη δομή C που είναι διαθέσιμες στο πρότυπο βιβλιοθήκης. Η ctypes μονάδα παρέχει μια τάξη δομή . Το παράδειγμα από τις docs:

>>> from ctypes import *
>>> class POINT(Structure):
...     _fields_ = [("x", c_int),
...                 ("y", c_int)]
...
>>> point = POINT(10, 20)
>>> print point.x, point.y
10 20
>>> point = POINT(y=5)
>>> print point.x, point.y
0 5
>>> POINT(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: too many initializers
>>>
>>> class RECT(Structure):
...     _fields_ = [("upperleft", POINT),
...                 ("lowerright", POINT)]
...
>>> rc = RECT(point)
>>> print rc.upperleft.x, rc.upperleft.y
0 5
>>> print rc.lowerright.x, rc.lowerright.y
0 0
>>>
Απαντήθηκε 25/06/2015 στις 22:50
πηγή χρήστη

ψήφοι
4

Έγραψα ένα διακοσμητή που μπορείτε να χρησιμοποιήσετε για οποιαδήποτε μέθοδο για να το κάνει, έτσι ώστε όλα τα επιχειρήματα που ψηφίστηκε το, ή οποιαδήποτε προεπιλογές, έχουν εκχωρηθεί στο παράδειγμα.

def argumentsToAttributes(method):
    argumentNames = method.func_code.co_varnames[1:]

    # Generate a dictionary of default values:
    defaultsDict = {}
    defaults = method.func_defaults if method.func_defaults else ()
    for i, default in enumerate(defaults, start = len(argumentNames) - len(defaults)):
        defaultsDict[argumentNames[i]] = default

    def newMethod(self, *args, **kwargs):
        # Use the positional arguments.
        for name, value in zip(argumentNames, args):
            setattr(self, name, value)

        # Add the key word arguments. If anything is missing, use the default.
        for name in argumentNames[len(args):]:
            setattr(self, name, kwargs.get(name, defaultsDict[name]))

        # Run whatever else the method needs to do.
        method(self, *args, **kwargs)

    return newMethod

Μια γρήγορη επίδειξη. Σημειώστε ότι μπορώ να χρησιμοποιήσω ένα θέσης επιχείρημα a, χρησιμοποιήστε την προεπιλεγμένη τιμή για b, και ονομάζεται επιχείρημα c. Στη συνέχεια εκτυπώστε όλες τις 3 αναφορά self, για να δείξουμε ότι έχουμε ήδη σωστά ανατεθεί πριν από την εισαγωγή της μεθόδου.

class A(object):
    @argumentsToAttributes
    def __init__(self, a, b = 'Invisible', c = 'Hello'):
        print(self.a)
        print(self.b)
        print(self.c)

A('Why', c = 'Nothing')

Σημειώστε ότι διακοσμητής μου πρέπει να συνεργαστεί με οποιαδήποτε μέθοδο, όχι μόνο __init__.

Απαντήθηκε 08/09/2015 στις 01:38
πηγή χρήστη

ψήφοι
1

Δεν βλέπω αυτή την απάντηση εδώ, έτσι μπορώ να καταλάβω εγώ θα το προσθέσετε αφού είμαι κλίνει Python τώρα και μόλις το ανακάλυψε. Το σεμινάριο Python (Python 2 στην περίπτωση αυτή) εκδίδει την ακόλουθη απλή και αποτελεσματική παράδειγμα:

class Employee:
    pass

john = Employee()  # Create an empty employee record

# Fill the fields of the record
john.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000

Δηλαδή, μια κενή κλάση αντικειμένου δημιουργείται, τότε αρχικοποιείται, και τα πεδία προστίθενται δυναμικά.

Η up-πλευρά σε αυτό είναι πραγματικά απλή του. Το μειονέκτημα είναι ότι δεν είναι ιδιαίτερα αυτο-τεκμηρίωση (τα προορισμό μέλη δεν αναφέρονται πουθενά στην κατηγορία «ορισμό»), και απενεργοποίηση πεδία μπορεί να προκαλέσει προβλήματα κατά την πρόσβαση. Αυτά τα δύο προβλήματα μπορούν να επιλυθούν με:

class Employee:
    def __init__ (self):
        self.name = None # or whatever
        self.dept = None
        self.salary = None

Τώρα με μια ματιά μπορείτε τουλάχιστον να δούμε τι πεδία, το πρόγραμμα θα πρέπει να περιμένουμε.

Και οι δύο είναι επιρρεπείς σε λάθη, john.slarly = 1000θα πετύχει. Ακόμα, λειτουργεί.

Απαντήθηκε 08/11/2016 στις 12:06
πηγή χρήστη

ψήφοι
0

Νομίζω ότι λεξικό δομή Python είναι κατάλληλη για αυτή την απαίτηση.

d = dict{}
d[field1] = field1
d[field2] = field2
d[field2] = field3
Απαντήθηκε 08/07/2017 στις 18:17
πηγή χρήστη

ψήφοι
35

Ενημέρωση : Μαθήματα Δεδομένων

Με την εισαγωγή των Κατηγοριών Δεδομένων στην Python 3.7 παίρνουμε πολύ κοντά.

Το ακόλουθο παράδειγμα είναι παρόμοιο με το NamedTuple παρακάτω παράδειγμα, αλλά το προκύπτον αντικείμενο είναι ευμετάβλητος και επιτρέπει για προεπιλεγμένες τιμές.

@dataclass
class Point:
    x: float
    y: float
    z: float = 0.0

p = Point(1.5, 2.5)
print(p)   # produces "Point(x=1.5, y=2.5, z=0.0)"

Αυτό παίζει πολύ καλά με τη νέα πληκτρολόγηση μονάδα σε περίπτωση που θέλετε να χρησιμοποιήσετε πιο συγκεκριμένες σχολιασμούς τύπου.

Έχω περιμένει απεγνωσμένα για αυτό! Αν με ρωτάτε, Μαθήματα δεδομένων και τη νέα NamedTuple δήλωση, σε συνδυασμό με την πληκτρολόγηση μονάδα είναι ένα απροσδόκητο καλό!

Βελτιωμένη declartaion NamedTuple

Από Python 3.6 έγινε αρκετά απλή και όμορφη (IMHO), εφ 'όσον μπορείτε να ζήσετε με αμετάβλητο.

Ένας νέος τρόπος δηλώνοντας NamedTuples εισήχθη, το οποίο επιτρέπει για σχολιασμούς τύπου καθώς:

from typing import NamedTuple

class MyStruct(NamedTuple):
    my_string: str
    my_int: int
    my_list: list
    my_dict: dict
    my_foo: Foo

Χρησιμοποιήστε το σαν αυτό:

my_item = MyStruct(
    my_string='foo',
    my_int=0,
    my_list=['bar'],
    my_dict={'baz': 'qux'},
    my_foo=Foo('bar')
)

Ή σαν αυτό, αν θέλετε πραγματικά να:

my_item = MyStruct('foo', 0, ['bar'], {'baz': 'qux'}, Foo('bar'))
Απαντήθηκε 31/07/2017 στις 21:54
πηγή χρήστη

ψήφοι
5

Μερικές απαντήσεις εδώ είναι μαζικά περίτεχνα. Η πιο απλή λύση που έχω βρει είναι (από: http://norvig.com/python-iaq.html ):

class Struct:
    "A structure that can have any fields defined."
    def __init__(self, **entries): self.__dict__.update(entries)

Εκκίνηση:

>>> options = Struct(answer=42, linelen=80, font='courier')
>>> options.answer
42

προσθέτοντας περισσότερα:

>>> options.cat = "dog"
>>> options.cat
dog

edit: Συγνώμη δεν είδα αυτό το παράδειγμα ήδη πιο κάτω.

Απαντήθηκε 04/08/2017 στις 23:39
πηγή χρήστη

ψήφοι
0

https://stackoverflow.com/a/32448434/159695 δεν λειτουργεί σε python3.

https://stackoverflow.com/a/35993/159695 λειτουργεί σε python3.

Και εγώ το επεκτείνει για να προσθέσετε προκαθορισμένες τιμές.

class myStruct:
    def __init__(self, **kwds):
        self.x=0
        self.__dict__.update(kwds) # Must be last to accept assigned member variable.
    def __repr__(self):
        args = ['%s=%s' % (k, repr(v)) for (k,v) in vars(self).items()]
        return '%s(%s)' % ( self.__class__.__qualname__, ', '.join(args) )

a=myStruct()
b=myStruct(x=3,y='test')
c=myStruct(x='str')

>>> a
myStruct(x=0)
>>> b
myStruct(x=3, y='test')
>>> c
myStruct(x='str')
Απαντήθηκε 30/10/2017 στις 11:40
πηγή χρήστη

ψήφοι
1

Προσωπικά, μου αρέσει αυτή η παραλλαγή πάρα πολύ. Επεκτείνει @ απάντηση dF του .

class struct:
    def __init__(self, *sequential, **named):
        fields = dict(zip(sequential, [None]*len(sequential)), **named)
        self.__dict__.update(fields)
    def __repr__(self):
        return str(self.__dict__)

Υποστηρίζει δύο τρόπους προετοιμασίας (που μπορεί να αναμιχθεί):

# Struct with field1, field2, field3 that are initialized to None.
mystruct1 = struct("field1", "field2", "field3") 
# Struct with field1, field2, field3 that are initialized according to arguments.
mystruct2 = struct(field1=1, field2=2, field3=3)

Επίσης, εκτυπώνει καλύτερο:

print(mystruct2)
# Prints: {'field3': 3, 'field1': 1, 'field2': 2}
Απαντήθηκε 06/11/2017 στις 13:38
πηγή χρήστη

ψήφοι
1

Η ακόλουθη λύση σε ένα struct είναι εμπνευσμένο από την εφαρμογή namedtuple και μερικές από τις προηγούμενες απαντήσεις. Ωστόσο, σε αντίθεση με την namedtuple είναι ευμετάβλητος, στις αξίες του, αλλά όπως το struct γ στιλ αμετάβλητο στα ονόματα / χαρακτηριστικά, που μια κανονική τάξη ή dict δεν είναι.

_class_template = """\
class {typename}:
def __init__(self, *args, **kwargs):
    fields = {field_names!r}

    for x in fields:
        setattr(self, x, None)            

    for name, value in zip(fields, args):
        setattr(self, name, value)

    for name, value in kwargs.items():
        setattr(self, name, value)            

def __repr__(self):
    return str(vars(self))

def __setattr__(self, name, value):
    if name not in {field_names!r}:
        raise KeyError("invalid name: %s" % name)
    object.__setattr__(self, name, value)            
"""

def struct(typename, field_names):

    class_definition = _class_template.format(
        typename = typename,
        field_names = field_names)

    namespace = dict(__name__='struct_%s' % typename)
    exec(class_definition, namespace)
    result = namespace[typename]
    result._source = class_definition

    return result

Χρήση:

Person = struct('Person', ['firstname','lastname'])
generic = Person()
michael = Person('Michael')
jones = Person(lastname = 'Jones')


In [168]: michael.middlename = 'ben'
Traceback (most recent call last):

  File "<ipython-input-168-b31c393c0d67>", line 1, in <module>
michael.middlename = 'ben'

  File "<string>", line 19, in __setattr__

KeyError: 'invalid name: middlename'
Απαντήθηκε 29/03/2018 στις 15:25
πηγή χρήστη

ψήφοι
1

Θα ήθελα επίσης να προσθέσω μια λύση που χρησιμοποιεί υποδοχές :

class Point:
    __slots__ = ["x", "y"]
    def __init__(self, x, y):
        self.x = x
        self.y = y

Σίγουρα ελέγξτε την τεκμηρίωση για υποδοχές, αλλά μια γρήγορη εξήγηση του διαθέσιμου χρόνου χρήσης είναι ότι είναι τρόπος πύθωνα του λέγοντας: «Αν μπορείτε να κλειδώσετε αυτά τα χαρακτηριστικά και μόνο αυτά τα χαρακτηριστικά στην τάξη, έτσι ώστε να δεσμευτεί ότι δεν θα προσθέσει νέα χαρακτηριστικά μία φορά την κατηγορία αρχικοποιείται (ναι, μπορείτε να προσθέσετε νέα χαρακτηριστικά σε περίπτωση τάξη, δείτε το παρακάτω παράδειγμα), τότε θα κάνω μακριά με το μεγάλο κατανομή μνήμης που επιτρέπει την προσθήκη νέων χαρακτηριστικών σε περίπτωση τάξη και χρησιμοποιούν ακριβώς αυτό που χρειάζεστε για αυτές τις σχισμές χαρακτηριστικά».

Παράδειγμα προσθήκη χαρακτηριστικών στην τάξη παράδειγμα (έτσι που δεν χρησιμοποιούν σχισμές):

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p1 = Point(3,5)
p1.z = 8
print(p1.z)

Έξοδος: 8

Παράδειγμα της προσπάθειας να προσθέσετε χαρακτηριστικά σε τάξη περίπτωση όπου χρησιμοποιήθηκε σχισμές:

class Point:
    __slots__ = ["x", "y"]
    def __init__(self, x, y):
        self.x = x
        self.y = y

p1 = Point(3,5)
p1.z = 8

Έξοδος: AttributeError: αντικείμενο «Σημείο» δεν έχει καμία ιδιότητα «z»

Αυτό μπορεί να λειτουργεί αποτελεσματικά ως ένα struct και χρησιμοποιεί λιγότερη μνήμη από μια κατηγορία (όπως ένα struct θα ήταν, αν και δεν έχω ερευνήσει ακριβώς πόσο). Συνιστάται η χρήση slots εάν θα δημιουργήσει ένα μεγάλο ποσό των εμφανίσεων του αντικειμένου και δεν χρειάζεται να προσθέσετε χαρακτηριστικά. Ένα αντικείμενο το σημείο είναι ένα καλό παράδειγμα αυτού, καθώς είναι πιθανό ότι μπορεί κανείς να υπόσταση σε πολλά σημεία για να περιγράψει ένα σύνολο δεδομένων.

Απαντήθηκε 12/04/2018 στις 05:17
πηγή χρήστη

ψήφοι
1

Υπάρχει ένα πακέτο python ακριβώς για το σκοπό αυτό. δείτε cstruct2py

cstruct2pyείναι ένα καθαρό βιβλιοθήκη python για τη δημιουργία τάξεων python από τον κώδικα C και να τα χρησιμοποιήσει για τη συσκευασία και την αποσυσκευασία των δεδομένων. Η βιβλιοθήκη μπορεί να αναλύσει C headres (Δομές, ενώσεις, enums, και δηλώσεις συστοιχίες) και να μιμηθεί τους στην Python. Τα παραγόμενα pythonic τάξεις μπορεί να αναλύσει και να συσκευάσει τα δεδομένα.

Για παράδειγμα:

typedef struct {
  int x;
  int y;
} Point;

after generating pythonic class...
p = Point(x=0x1234, y=0x5678)
p.packed == "\x34\x12\x00\x00\x78\x56\x00\x00"

Πώς να χρησιμοποιήσετε

Πρώτα πρέπει να δημιουργήσουν τις Δομές pythonic:

import cstruct2py
parser = cstruct2py.c2py.Parser()
parser.parse_file('examples/example.h')

Τώρα μπορούμε να εισάγουμε όλα τα ονόματα από τον κώδικα C:

parser.update_globals(globals())

Μπορούμε επίσης να κάνουμε αυτό ακριβώς:

A = parser.parse_string('struct A { int x; int y;};')

Χρησιμοποιώντας τους τύπους και ορίζει από τον κώδικα C

a = A()
a.x = 45
print a
buf = a.packed
b = A(buf)
print b
c = A('aaaa11112222', 2)
print c
print repr(c)

Η έξοδος θα είναι:

{'x':0x2d, 'y':0x0}
{'x':0x2d, 'y':0x0}
{'x':0x31316161, 'y':0x32323131}
A('aa111122', x=0x31316161, y=0x32323131)

κλώνος

Για κλώνος cstruct2pyτρέχει:

git clone https://github.com/st0ky/cstruct2py.git --recursive
Απαντήθηκε 11/12/2018 στις 07:34
πηγή χρήστη

ψήφοι
0

Αν δεν έχετε ένα 3.7 για @dataclass και πρέπει μεταβλητότητα, ο κώδικας που ακολουθεί θα μπορούσε να λειτουργήσει για σας. Είναι αρκετά αυτο-καταγραφή και IDE-φιλικό (auto-complete), αποτρέπει το γράψιμο τα πράγματα δύο φορές, είναι εύκολα επεκτάσιμο και είναι πολύ απλό να ελέγξετε ότι όλες οι μεταβλητές παράδειγμα είναι πλήρως προετοιμαστεί:

class Params():
    def __init__(self):
        self.var1 : int = None
        self.var2 : str = None

    def are_all_defined(self):
        for key, value in self.__dict__.items():
            assert (value is not None), "instance variable {} is still None".format(key)
        return True


params = Params()
params.var1 = 2
params.var2 = 'hello'
assert(params.are_all_defined)
Απαντήθηκε 28/01/2019 στις 09:27
πηγή χρήστη

ψήφοι
0

Εδώ είναι μια λύση η οποία χρησιμοποιεί μια τάξη (δεν αρχικοποιείται) για να κρατήσει τα δεδομένα. Μου αρέσει ότι με τον τρόπο αυτό συνεπάγεται πολύ μικρή πληκτρολόγηση και δεν απαιτεί καμία επιπλέον πακέτα κ.λπ.

class myStruct:
    field1 = "one"
    field2 = "2"

Μπορείτε να προσθέσετε περισσότερα πεδία αργότερα, ανάλογα με τις ανάγκες:

myStruct.field3 = 3

Για να πάρετε τις τιμές, τα πεδία πρόσβαση ως συνήθως:

>>> myStruct.field1
'one'
Απαντήθηκε 09/04/2019 στις 10:10
πηγή χρήστη

ψήφοι
0

Εδώ είναι μια γρήγορη και βρώμικο κόλπο:

>>> ms = Warning()
>>> ms.foo = 123
>>> ms.bar = 'akafrit'

Πώς λειτουργεί; Απλά χρησιμοποιήσετε ξανά την ενσωματωμένη τάξη Warning(που προέρχεται από το Exception) και να το χρησιμοποιήσετε όπως ήταν δική σας ορίζεται τάξη.

Τα καλά σημεία είναι ότι δεν χρειάζεται να εισάγει ή να καθορίσει τίποτα πρώτο, ότι «Προειδοποίηση» είναι ένα σύντομο όνομα, και αυτό καθιστά επίσης σαφές κάνετε κάτι βρώμικο που δεν πρέπει να χρησιμοποιηθούν αλλού από ένα μικρό σενάριο σου.

Με την ευκαιρία, προσπάθησα να βρω κάτι ακόμα πιο απλό, όπως ms = object(), αλλά δεν μπορούσε (αυτό το τελευταίο Exemple δεν λειτουργεί). Εάν έχετε ένα, ενδιαφέρομαι.

Απαντήθηκε 26/09/2019 στις 15:56
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more