Δημοσιεύτηκε: 26 Ιουν 2014, 06:43
Ilias95 έγραψε:lucinos έγραψε:Η αλήθεια είναι ότι οι κλάσσεις δεν είναι το δυνατό σημείο τής Python.
Μπορείς να το εξηγήσεις αυτό;
Η Python σχεδιάστηκε αρχικά δίχως κλάσσεις. Αυτό ακόμα και αν δεν ξέρεις ιστορία είναι οφθαλμοφανές στην Python2. πχ
- Κώδικας: Επιλογή όλων
Python 2.7.7 (default, Jun 3 2014, 01:46:20)
[GCC 4.9.0 20140521 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> type(2)
<type 'int'>
>>>
Η Python3 έχει απλοποιηθεί συντακτικά:
- Κώδικας: Επιλογή όλων
Python 3.4.1 (default, May 19 2014, 17:23:49)
[GCC 4.9.0 20140507 (prerelease)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> type(2)
<class 'int'>
>>>
Όμως (και κατά την γνώμη μου άριστα) η Python δεν άλλαξε χαρακτήρα. Η Python παραμένει Python και οι κλάσσεις δεν είναι το ισχυρό χαρακτηριστικό. Το ισχυρό χαρακτηριστικό τής γλώσσας είναι οι συναρτήσεις.
έγραψε:lucinos έγραψε:Στην πράξη κλάσεις χρησιμοποιείς αρκετά συχνά, αλλά ποτέ δεν θα χρειαστείς να φτιάξεις μία ή να δεις τον κώδικα μίας στην Python.
Wut?
Όταν κάποιος χρησιμοποιεί ένα οποιοδήποτε άρθρωμα, κατά πάσα πιθανότητα χρησιμοποιεί κλάσσεις. Αλλά αυτό δεν ενδιαφέρει τον προγραμματιστή-χρήστη. Γιατί τότε απλά θα κοιτάξει πώς χρησιμοποιούνται τα συγκεκριμένα αντικείμενα. Δηλαδή τις κλάσσεις στην Python τις βλέπω κυρίως σαν εργαλεία που φτιάχνουν προγραμματιστές για άλλους προγραμματιστές (ως τέτοια εργαλεία είναι εξαιρετικά χρήσιμες). Ένας προγραμματιστής ποτέ δεν χρειάζεται να φτιάξει μια κλάσση για τον εαυτό του (μιλώ για την Python πάντα). Υπάρχει πάντα κάτι έτοιμο που είναι αρκετό.
Ο μόνος λόγος που προσωπικά θα έφτιαχνα κλάσση είναι για να υπερφορτώσω τελεστές. Και στην πραγματικότητα το έχω κάνει αυτό! Έχω φτιάξει κλάσση για "quaternion"! Το "quaternion" (τετραδικούς τούς ήξερα, τώρα βλέπω στην βικιπαίδεια τον όρο «τετραδόνια» είναι κατά κάποιον τρόπο επέκταση τών μιγαδικών. Περισσότερα μπορείτε να δείτε στο άρθρο τής βικιπαίδειας: Quaternion και Τετραδόνιο
Μάλιστα πάρτε και τον κώδικά μου να τον έχετε:
- Κώδικας: Επιλογή όλων
import math
class Quaternion(object):
def __init__(self, w=0.0, x=0.0, y=0.0, z=0.0):
self.w = float(w)
self.x = float(x)
self.y = float(y)
self.z = float(z)
def __repr__(self):
return quat_repr(self)
def __add__(self, other):
return quat_add(self, other)
def __radd__(self, other):
return quat_add(other, self)
def __neg__(self):
return Quaternion(-self.w, -self.x, -self.y, -self.z)
def __sub__(self, other):
return quat_add(self, - other)
def __rsub__(self, other):
return quat_add(other, - self)
def __mul__(self, other):
return quat_mul(self, other)
def __rmul__(self, other):
return quat_mul(other, self)
def __truediv__(self, other):
return quat_div(self, other)
def __rtruediv__(self, other):
return quat_div(other, self)
def __abs__(self):
return math.sqrt(
self.w * self.w
+ self.x * self.x
+ self.y * self.y
+ self.z * self.z
)
def __invert__(q):
"""Conjugate of Quaternion.
>>> q = Quaternion((2, 2, 2, 2))
>>> print(q)
(2 + 2i + 2j + 2k)
>>> print(~q)
(2 - 2i - 2j - 2k)
>>> print(~~q)
(2 + 2i + 2j + 2k)
"""
return Quaternion(q.w, -q.x, -q.y, -q.z)
def as_tuple(self):
return (self.w, self.x, self.y, self.z)
def normalize(q):
"""Convert Quaternion to Unit Quaternion.
Unit Quaternion is Quaternion who's length is equal to 1.
>>> q = Quaternion((1, 3, 3, 3))
>>> q.normalize()
>>> print(q) # doctest: +ELLIPSIS
(0.1889822... + 0.5669467...i + 0.5669467...j + 0.5669467...k)
"""
norm = abs(q)
q.w = q.w / norm
q.x = q.x / norm
q.y = q.y / norm
q.z = q.z / norm
def signed_repr(x):
if x < 0:
return repr(x)
else:
return '+' + repr(x)
def quat_repr(q):
return '{0} {1}i {2}j {3}k'.format(
signed_repr(q.w),
signed_repr(q.x),
signed_repr(q.y),
signed_repr(q.z),
)
def quat_get(q):
try:
w = float(q)
x = 0.0
y = 0.0
z = 0.0
return Quaternion(w, x, y, z)
except TypeError:
return q
def quat_add(q1, q2):
q1 = quat_get(q1)
q2 = quat_get(q2)
return Quaternion(
q1.w + q2.w,
q1.x + q2.x,
q1.y + q2.y,
q1.z + q2.z,
)
def quat_mul(q1, q2):
q1 = quat_get(q1)
q2 = quat_get(q2)
return Quaternion(
q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z,
q1.w*q2.x + q1.x*q2.w + q1.y*q2.z - q1.z*q2.y,
q1.w*q2.y - q1.x*q2.z + q1.y*q2.w + q1.z*q2.x,
q1.w*q2.z + q1.x*q2.y - q1.y*q2.x + q1.z*q2.w,
)
def quat_div(q1, q2):
q1 = quat_get(q1)
q2 = quat_get(q2)
s = float(q2.w*q2.w + q2.x*q2.x + q2.y*q2.y + q2.z*q2.z)
return Quaternion(
( q1.w*q2.w + q1.x*q2.x + q1.y*q2.y + q1.z*q2.z) / s,
(- q1.w*q2.x + q1.x*q2.w + q1.y*q2.z - q1.z*q2.y) / s,
(- q1.w*q2.y - q1.x*q2.z + q1.y*q2.w + q1.z*q2.x) / s,
(- q1.w*q2.z + q1.x*q2.y - q1.y*q2.x + q1.z*q2.w) / s,
)
Ο κώδικας αυτός είναι δικός μου, πλην τών μεθόδων __invert__ και normalize (φαίνεται!). Εδώ φαίνεται και ένας προσωπικός μου κανόνας για τις κλάσσεις. Είναι πιστεύω λάθος να βάζουμε μη τετριμμένο κώδικα στις κλάσσεις. Αυτός που κοιτάει μια κλάσση θέλει να δει τι μεθόδους περιέχει. Ο όποιος κώδικας «κάνει δουλειά» πρέπει πάντα να βρίσκεται σε συναρτήσεις έξω από τις κλάσσεις. (διαφορετικά συσκοτίζει την κλάσση)
Δίνω παράδειγμα χρήσης σε ipython
- Κώδικας: Επιλογή όλων
In [1]: import my_quaternion as quat
In [2]: q = quat.Quaternion(2,2,2,2)
In [3]: q
Out[3]: +2.0 +2.0i +2.0j +2.0k
In [4]: print(q)
+2.0 +2.0i +2.0j +2.0k
In [5]: 3-q
Out[5]: +1.0 -2.0i -2.0j -2.0k
In [6]: ~q
Out[6]: +2.0 -2.0i -2.0j -2.0k
In [7]: q*2
Out[7]: +4.0 +4.0i +4.0j +4.0k
In [8]: q*q
Out[8]: -8.0 +8.0i +8.0j +8.0k
In [9]: abs(q)
Out[9]: 4.0
In [10]: 3/q
Out[10]: +0.375 -0.375i -0.375j -0.375k
In [11]: