class UserCreationForm(forms.ModelForm):
"""
A form that creates a user, with no privileges,
from the given username and password.
"""
username = forms.RegexField(
label=_("Username"),
max_length=30,
regex=r'^[\w.@+-]+$')
password1 = forms.CharField(
label=_("Password"),
widget=forms.PasswordInput)
password2 = forms.CharField(
label=_("Password confirmation"),
widget=forms.PasswordInput)
class Meta: # Meta, WTF ?
model = User
fields = ("username",)
class Comment(BaseCommentAbstractModel):
"""
A user comment about some object.
"""
user = models.ForeignKey(User, verbose_name=_('user'),
blank=True, null=True,
related_name="%(class)s_comments")
user_name = models.CharField(_("user's name"),
max_length=50, blank=True)
user_email = models.EmailField(_("user's email address"),
blank=True)
user_url = models.URLField(_("user's URL"), blank=True)
comment = models.TextField(_('comment'),
max_length=COMMENT_MAX_LENGTH)
# Metadata about the comment
submit_date = models.DateTimeField(_('date/time submitted'),
default=None)
ip_address = models.IPAddressField(_('IP address'),
blank=True, null=True)
class ProductFilter(django_filters.FilterSet):
price = django_filters.NumberFilter(
lookup_type='lt')
class Meta:
model = Product
fields = ['price', 'release_date']
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Person(Base):
__tablename__ = 'people'
id = Column(Integer, primary_key=True)
discriminator = Column('type', String(50))
__mapper_args__ = {'polymorphic_on': discriminator}
class Engineer(Person):
__tablename__ = 'engineers'
__mapper_args__ = {'polymorphic_identity': 'engineer'}
id = Column(Integer, ForeignKey('people.id'),
primary_key=True)
primary_language = Column(String(50))
@inpacket(0x01)
class WelcomePacket(GaduPacket):
seed = numeric.IntField(0)
@inpacket(0x05)
class MessageAckPacket(GaduPacket): #SendMsgAck
MSG_STATUS = Enum({
'BLOCKED': 0x0001, 'DELIVERED': 0x0002,
'QUEUED': 0x0003, 'MBOXFULL': 0x0004,
'NOT_DELIVERED': 0x0006
})
msg_status = numeric.IntField(0)
recipient = numeric.IntField(1)
seq = numeric.IntField(2)
PyStruct
.__tablename__
, `class Meta``, które są
tylko w definicji.# Python 2
class A(object):
x = 10
# Python 3
class A:
x = 10
# Co się właściwie stanie ?
name = "A"
bases = (object,)
def _A():
x = 10
# Python 2
body = {}
# Python 3
body = type.__prepare__(name, bases)
# i dalej:
exec(_A.__code__, body, globals())
A = type(name, bases, body)
type
?Formalnie jest to dowolny obiekt wywoływalny (ang. callable) przyjmujący
wymienione trzy argumenty: name
, bases
i body
.
(Py3k) Jeśli obiekt ma atrybut __prepare__
, to jest wywoływany
z argumentami name
i bases
do stworzenia body
.
def meta(*args):
print(args)
return type(*args)
# Python 2
class B(A):
__metaclass__ = meta
# Python 3
class B(A, metaclass=meta):
pass
Metaklasa jest wybierana na podstawie prostego algorytmu:
if meta:
isclass = issubclass(meta, type)
else:
if not bases:
meta = type
else:
meta = bases[0].__class__
isclass = True
if isclass:
for base in bases:
if issubclass(meta, base):
continue
if issubclass(base, meta):
meta = base
continue
raise TypeError("Konflikt")
return meta
A = meta(name, bases, body)
# znów rozwijamy:
A = meta.__call__(name, bases, body)
# jeśli ``meta`` jest klasą
A = meta.__new__(name, bases, body)
if isinstance(A, meta):
meta.__init__(A, name, bases, body)
Będziemy więc nadpisywać __new__
albo __init__
w zależności od potrzeb.
Potrzebujemy osobnej klasy bazowej dla pól (może być abstrakcyjna,
patrz moduł abc
), aby móc rozróżnić je od zwykłych metod.
Musimy też rozwiązać jakoś problem kolejności, gdyż domyślnie nazwy zdefiniowane w ciele klasy są wkładane do słownika.
class BaseField(object):
_creation_counter = 0
def __new__(cls, *args, **kwargs):
instance = super(BaseField, cls).__new__(cls, *args, **kwargs)
instance._creation_counter = BaseField._creation_counter
BaseField._creation_counter += 1
class DMeta(type):
def __new__(mcls, name, bases, body):
fields = []
for name, field in body.items():
if not isinstance(field, BaseField):
continue
body.pop(name) # opcjonalne
fields.append((name, field))
fields.sort(key=lambda f: f[1]._creation_counter)
cls = super(DMeta, mcls).__new__(mcls, name, bases, body)
# Zsumuj definicję
base_fields = []
for base in bases:
base_fields.extend(base._fields.items())
cls._fields = collections.OrderedDict(base_fields + fields)
for name, field in cls._fields.items():
field.contribute_to_class(name, cls)
return cls
class DMeta(type):
@classmethod
def __prepare__(mcls, name, bases):
return collections.OrderedDict()
def __new__(mcls, name, bases, body):
fields = []
for name, field in body.items():
if not hasattr("contribute_to_class", field):
continue
body.pop(name) # opcjonalne
fields.append((name, field))
cls = super().__new__(mcls, name, bases, body)
# Zsumuj definicję
base_fields = []
for base in bases:
base_fields.extend(base._fields.items())
cls._fields = collections.OrderedDict(base_fields + fields)
for name, field in cls._fields.items():
field.contribute_to_class(name, cls)
return cls
Meta
class Struct(metaclass=DMeta):
one = Field()
two = Field()
class Meta:
unique_together = [('one', 'two')]
Pozwala definiować dodatkowe własności nie związane z konkretnym
polem unikająć kolizji z nazwami pól, bez używania wszędzie __
i
nie zaśmiecając klasy.
# Formularze Django:
class ArticleForm(forms.Form):
title = forms.CharField()
category = forms.CharField(max_length=1,
choices=(("N", "News"), ("R", "Review"))
# Teraz chcemy stworzyć specjalny formularz dla News, więc
# musimy ograniczyć category
# Nie zadziała:
class NewsForm(ArticleForm):
category.choices = ((1, "News"),)
# Można tak, ale musimy powtórzyć
# wszystkie inne opcje
class NewsForm(ArticleForm):
category = forms.CharField(max_length=1,
choices=(("N", "News"),))
class ExtMeta(DMeta):
@classmethod
def __prepare__(mcls, name, bases):
d = super().__prepare__(name, bases)
for base in bases:
for name, field in base._fields.items():
d[name] = field.clone()
return d
class NewsForm(ArticleForm, metaclass=ExtMeta):
category.choices = ((1, "News"),)
Meta
class Options(object):
def __init__(self, *base_options):
self.unique_tuples = []
for base in base_options:
self.unique_tuples.extend(base.unique_tuples)
def add_unique(self, *fields):
self.unique_tuples.append(fields)
class OptsMeta(ExtMeta):
@classmethod
def __prepare__(mcls, name, bases, **kwargs):
d = super().__prepare__(name, bases)
d["Meta"] = Options(*[base._options for base in bases])
return d
def __new__(mcls, name, bases, body, **kwargs):
options = body.pop("Meta")
cls = super().__new__(mcls, name, bases, body)
cls._options = options
return cls
def __init__(cls, name, bases, body, abstract=False):
cls.abstract = abstract
Meta
class Field:
def contribute_to_class(self, name, cls):
pass
def clone(self):
return copy.copy(self)
class Base(metaclass=OptsMeta):
pass
class A(Base, abstract=True):
a = Field()
class B(A):
b = Field()
Meta.add_unique(a, b)
Table of Contents | t |
---|---|
Exposé | ESC |
Full screen slides | e |
Presenter View | p |
Source Files | s |
Slide Numbers | n |
Toggle screen blanking | b |
Show/hide slide context | c |
Notes | 2 |
Help | h |