Системы основывались на платформах (.net, Java, и т.д.) решения. Правительство платит (охотно) за решение, но ROI намного выше, чем другие методы для получения того же результата.
правительство покупает много вещей, которые оно не делает интеллектуально собственный, потому что ему нужен продукт/решение. Миллионы примеров там.
Обновление варианта ThomasH:
def Struct(*args, **kwargs):
def init(self, *iargs, **ikwargs):
for k,v in kwargs.items():
setattr(self, k, v)
for i in range(len(iargs)):
setattr(self, args[i], iargs[i])
for k,v in ikwargs.items():
setattr(self, k, v)
name = kwargs.pop("name", "MyStruct")
kwargs.update(dict((k, None) for k in args))
return type(name, (object,), {'__init__': init, '__slots__': kwargs.keys()})
Это позволяет передавать параметры (и именованные параметры) в __ init __ ()
(без какой-либо проверки - кажется грубым):
>>> Person = Struct('fname', 'age')
>>> person1 = Person('Kevin', 25)
>>> person2 = Person(age=42, fname='Terry')
>>> person1.age += 10
>>> person2.age -= 10
>>> person1.fname, person1.age, person2.fname, person2.age
('Kevin', 35, 'Terry', 32)
>>>
Рассмотрим, как namedtuple ()
делает это в collections.py . Класс создается и расширяется как строка и оценивается. Также есть поддержка травления и т. Д.
Существует namedtuple
>>> from collections import namedtuple
>>> Person = namedtuple("Person", ("forename", "surname"))
>>> john = Person("John", "Doe")
>>> john.forename
'John'
>>> john.surname
'Doe'
Это продолжение ответа Cide (и, вероятно, интересно только тем, кто хочет копнуть глубже).
Я столкнулся с проблемой при использовании обновленного определения Cide для Struct (), использующего __slots__. Проблема в том, что экземпляры возвращаемых классов имеют атрибуты только для чтения:
>>> MS = Struct('forename','lastname')
>>> m=MS()
>>> m.forename='Jack'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'MyStruct' object attribute 'forename' is read-only
Похоже, что __slots__ блокирует атрибуты уровня экземпляра, когда есть атрибуты класса с одинаковыми именами. Я попытался преодолеть это, предоставив метод __init__, поэтому атрибуты экземпляра могут быть установлены во время создания объекта:
def Struct1(*args, **kwargs):
def init(self):
for k,v in kwargs.items():
setattr(self, k, v)
name = kwargs.pop("name", "MyStruct")
kwargs.update(dict((k, None) for k in args))
return type(name, (object,), {'__init__': init, '__slots__': kwargs.keys()})
В качестве общего эффекта сконструированный класс видит только метод __init__ и член __slots__, который работает должным образом:
>>> MS1 = Struct1('forename','lastname')
>>> m=MS1()
>>> m.forename='Jack'
>>> m.forename
'Jack'
Если вы используете Python 2.6, попробуйте класс стандартной библиотеки namedtuple .
>>> from collections import namedtuple
>>> Person = namedtuple('Person', ('forename', 'surname'))
>>> person1 = Person('John', 'Doe')
>>> person2 = Person(forename='Adam', surname='Monroe')
>>> person1.forename
'John'
>>> person2.surname
'Monroe'
Правка: Согласно комментариям, существует резервный порт для более ранних версий Python
Как и другие сказал, именованные кортежи в Python 2.6 / 3.x. В более старых версиях я обычно использую класс Stuff:
class Stuff(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
john = Stuff(forename='John', surname='Doe')
Однако это не защищает вас от неправильного написания. Также есть рецепт для именованных кортежей в ActiveState:
Если вы используете python <2.6 или хотите расширить свой класс, чтобы делать больше, я бы предложил использовать встроенную функцию type ()
. Это имеет преимущество перед вашим решением в том, что установка __ dict __
происходит при создании класса, а не при создании экземпляра. Он также не определяет метод __ init __
и, следовательно, не приводит к странному поведению, если по какой-то причине класс снова вызывает __ init __
. Например:
def Struct(*args, **kwargs):
name = kwargs.pop("name", "MyStruct")
kwargs.update(dict((k, None) for k in args))
return type(name, (object,), kwargs)
Используется так:
>>> MyStruct = Struct("forename", "lastname")
Эквивалентно:
class MyStruct(object):
forename = None
lastname = None
В то время как это:
>>> TestStruct = Struct("forename", age=18, name="TestStruct")
Эквивалентно:
class TestStruct(object):
forename = None
age = 18
Обновление
Кроме того, вы можете отредактировать этот код, чтобы очень легко предотвратить назначение других переменные, чем указанные. Просто измените фабрику Struct (), чтобы назначить __ slots __
.
def Struct(*args, **kwargs):
name = kwargs.pop("name", "MyStruct")
kwargs.update(dict((k, None) for k in args))
kwargs['__slots__'] = kwargs.keys()
return type(name, (object,), kwargs)