Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
27e4aa31
Kaydet (Commit)
27e4aa31
authored
Agu 25, 1997
tarafından
Guido van Rossum
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Arbitrary point checkpoint commit. Take no notice.
üst
bff110f3
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
248 additions
and
6 deletions
+248
-6
Eiffel.py
Demo/metaclasses/Eiffel.py
+113
-0
Enum.py
Demo/metaclasses/Enum.py
+5
-1
Meta.py
Demo/metaclasses/Meta.py
+106
-0
Trace.py
Demo/metaclasses/Trace.py
+24
-5
No files found.
Demo/metaclasses/Eiffel.py
0 → 100644
Dosyayı görüntüle @
27e4aa31
"""Support Eiffel-style preconditions and postconditions.
For example,
class C:
def m1(self, arg):
require arg > 0
return whatever
ensure Result > arg
can be written (clumsily, I agree) as:
class C(Eiffel):
def m1(self, arg):
return whatever
def m1_pre(self, arg):
assert arg > 0
def m1_post(self, Result, arg):
assert Result > arg
Pre- and post-conditions for a method, being implemented as methods
themselves, are inherited independently from the method. This gives
much of the same effect of Eiffel, where pre- and post-conditions are
inherited when a method is overridden by a derived class. However,
when a derived class in Python needs to extend a pre- or
post-condition, it must manually merge the base class' pre- or
post-condition with that defined in the derived class', for example:
class D(C):
def m1(self, arg):
return whatever**2
def m1_post(self, Result, arg):
C.m1_post(self, Result, arg)
assert Result < 100
This gives derived classes more freedom but also more responsibility
than in Eiffel, where the compiler automatically takes care of this.
In Eiffel, pre-conditions combine using contravariance, meaning a
derived class can only make a pre-condition weaker; in Python, this is
up to the derived class. For example, a derived class that takes away
the requirement that arg > 0 could write:
def m1_pre(self, arg):
pass
but one could equally write a derived class that makes a stronger
requirement:
def m1_pre(self, arg):
require arg > 50
It would be easy to modify the classes shown here so that pre- and
post-conditions can be disabled (separately, on a per-class basis).
A different design would have the pre- or post-condition testing
functions return true for success and false for failure. This would
make it possible to implement automatic combination of inherited
and new pre-/post-conditions. All this is left as an exercise to the
reader.
"""
from
Meta
import
MetaClass
,
MetaHelper
,
MetaMethodWrapper
class
EiffelMethodWrapper
(
MetaMethodWrapper
):
def
__init__
(
self
,
func
,
inst
):
MetaMethodWrapper
.
__init__
(
self
,
func
,
inst
)
# Note that the following causes recursive wrappers around
# the pre-/post-condition testing methods. These are harmless
# but inefficient; to avoid them, the lookup must be done
# using the class.
try
:
self
.
pre
=
getattr
(
inst
,
self
.
__name__
+
"_pre"
)
except
AttributeError
:
self
.
pre
=
None
try
:
self
.
post
=
getattr
(
inst
,
self
.
__name__
+
"_post"
)
except
AttributeError
:
self
.
post
=
None
def
__call__
(
self
,
*
args
,
**
kw
):
if
self
.
pre
:
apply
(
self
.
pre
,
args
,
kw
)
Result
=
apply
(
self
.
func
,
(
self
.
inst
,)
+
args
,
kw
)
if
self
.
post
:
apply
(
self
.
post
,
(
Result
,)
+
args
,
kw
)
return
Result
class
EiffelHelper
(
MetaHelper
):
__methodwrapper__
=
EiffelMethodWrapper
class
EiffelMetaClass
(
MetaClass
):
__helper__
=
EiffelHelper
Eiffel
=
EiffelMetaClass
(
'Eiffel'
,
(),
{})
def
_test
():
class
C
(
Eiffel
):
def
m1
(
self
,
arg
):
return
arg
+
1
def
m1_pre
(
self
,
arg
):
assert
arg
>
0
,
"precondition for m1 failed"
def
m1_post
(
self
,
Result
,
arg
):
assert
Result
>
arg
x
=
C
()
x
.
m1
(
12
)
x
.
m1
(
-
1
)
if
__name__
==
'__main__'
:
_test
()
Demo/metaclasses/Enum.py
Dosyayı görüntüle @
27e4aa31
"""Enumeration metaclass."""
"""Enumeration metaclass.
XXX This is very much a work in progress.
"""
import
string
...
...
Demo/metaclasses/Meta.py
0 → 100644
Dosyayı görüntüle @
27e4aa31
"""Generic metaclass.
XXX This is very much a work in progress.
"""
import
types
class
MetaMethodWrapper
:
def
__init__
(
self
,
func
,
inst
):
self
.
func
=
func
self
.
inst
=
inst
self
.
__name__
=
self
.
func
.
__name__
def
__call__
(
self
,
*
args
,
**
kw
):
return
apply
(
self
.
func
,
(
self
.
inst
,)
+
args
,
kw
)
class
MetaHelper
:
__methodwrapper__
=
MetaMethodWrapper
# For derived helpers to override
def
__helperinit__
(
self
,
formalclass
):
self
.
__formalclass__
=
formalclass
def
__getattr__
(
self
,
name
):
# Invoked for any attr not in the instance's __dict__
try
:
raw
=
self
.
__formalclass__
.
__getattr__
(
name
)
except
AttributeError
:
try
:
_getattr_
=
self
.
__dict__
[
'_getattr_'
]
except
KeyError
:
raise
AttributeError
,
name
return
_getattr_
(
name
)
if
type
(
raw
)
!=
types
.
FunctionType
:
return
raw
return
self
.
__methodwrapper__
(
raw
,
self
)
class
MetaClass
:
"""A generic metaclass.
This can be subclassed to implement various kinds of meta-behavior.
"""
__helper__
=
MetaHelper
# For derived metaclasses to override
__inited
=
0
def
__init__
(
self
,
name
,
bases
,
dict
):
if
dict
.
has_key
(
'__getattr__'
):
raise
TypeError
,
"Can't override __getattr__; use _getattr_"
self
.
__name__
=
name
self
.
__bases__
=
bases
self
.
__realdict__
=
dict
self
.
__inited
=
1
def
__getattr__
(
self
,
name
):
try
:
return
self
.
__realdict__
[
name
]
except
KeyError
:
for
base
in
self
.
__bases__
:
try
:
return
base
.
__getattr__
(
name
)
except
AttributeError
:
pass
raise
AttributeError
,
name
def
__setattr__
(
self
,
name
,
value
):
if
not
self
.
__inited
:
self
.
__dict__
[
name
]
=
value
else
:
self
.
__realdict__
[
name
]
=
value
def
__call__
(
self
,
*
args
,
**
kw
):
inst
=
self
.
__helper__
()
inst
.
__helperinit__
(
self
)
try
:
init
=
inst
.
__getattr__
(
'__init__'
)
except
AttributeError
:
init
=
lambda
:
None
apply
(
init
,
args
,
kw
)
return
inst
Meta
=
MetaClass
(
'Meta'
,
(),
{})
def
_test
():
class
C
(
Meta
):
def
__init__
(
self
,
*
args
):
print
"__init__, args ="
,
args
def
m1
(
self
,
x
):
print
"m1(x=
%
s)"
%
`x`
print
C
x
=
C
()
print
x
x
.
m1
(
12
)
if
__name__
==
'__main__'
:
_test
()
Demo/metaclasses/Trace.py
Dosyayı görüntüle @
27e4aa31
"""Tracing metaclass.
"""
"""Tracing metaclass.
import
types
XXX This is very much a work in progress.
"""
import
types
,
sys
class
TraceMetaClass
:
"""Metaclass for tracing.
...
...
@@ -28,7 +32,7 @@ class TraceMetaClass:
except
KeyError
:
for
base
in
self
.
__bases__
:
try
:
return
getattr
(
base
,
name
)
return
base
.
__getattr__
(
name
)
except
AttributeError
:
pass
raise
AttributeError
,
name
...
...
@@ -106,12 +110,15 @@ Traced = TraceMetaClass('Traced', (), {'__trace_output__': None})
def
_test
():
import
sys
global
C
,
D
class
C
(
Traced
):
def
__init__
(
self
,
x
=
0
):
self
.
x
=
x
def
m1
(
self
,
x
):
self
.
x
=
x
def
m2
(
self
,
y
):
return
self
.
x
+
y
C
.
__trace_output__
=
sys
.
stdout
__trace_output__
=
sys
.
stdout
class
D
(
C
):
def
m2
(
self
,
y
):
print
"D.m2(
%
s)"
%
`y`
;
return
C
.
m2
(
self
,
y
)
__trace_output__
=
None
x
=
C
(
4321
)
print
x
print
x
.
x
...
...
@@ -122,5 +129,17 @@ def _test():
print
x
.
m2
(
4000
)
print
x
.
x
print
C
.
__init__
print
C
.
m2
print
D
.
__init__
print
D
.
m2
y
=
D
()
print
y
print
y
.
m1
(
10
)
print
y
.
m2
(
100
)
print
y
.
x
if
__name__
==
'__main__'
:
_test
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment