"Python" "Xulie ' update&sanlie&cisling.py"

Source: Internet
Author: User
Tags abs


"""
From array Import array
Import Reprlib
array1 = Array (' d ', (+/-))
Print (array1) #array (' d ', [1.0, 2.0, 3.0])
com = REPRLIB.REPR (array1)
components = Com[com.find (' ['):-1]
Print (' Vector ({}) '. Format (components)) #Vector ([1.0, 2.0, 3.0])
"""
#10.2 Vector class first edition, compatible with VECTOR2D class
#例子10-2
From array Import array
Import Reprlib
Import Math
Import numbers
Import Functools
Import operator
Import Itertools

Class Vector:
TypeCode = ' d '

def __init__ (self,components):
self._components = Array (self.typecode,components) # Keep vector components in an array

def __iter__ (self):
Return iter (self._components) #构造一个迭代器

def __repr__ (self):
components = Reprlib.repr (self._components) #使用reprlib. REPR () Gets the finite-length representation of self._components, such as Array (' d ', [ 0.0,1.0,2.0,3.0,4.0,...]) )
components = Components[components.find (' ['): -1] #把字符串插入Vector的构造方法调用之前, remove the preceding array (' d ' and back)
Return ' Vector ({}) '. Format (components)
‘‘‘
def __str__ (self):
Return str (tuple (self))
‘‘‘
__str__ = __repr__

def __bytes__ (self):
Return (bytes ([Ord (Self.typecode)]) + bytes (self._components)) #直接用self. _components Build Bytes Objects
def __eq__ (self, Other):
return tuple (self) = = Tuple (Other)
def __abs__ (self):
return math.sqrt (SUM (x*x for x in self) #不能直接用hypot方法了, so we first calculate the sum of the squares of each component, and then use the Sqrt method to open the square
def __bool__ (self):
return BOOL (ABS (self))
@classmethod
def frombytes (cls,octets):
TypeCode = Chr (Octets[0])
MEMV = Memoryview (octets[1:]). CAST (TypeCode)
Return CLS (MEMV) #构造方法变了, so do not use * unpacking as before
def __len__ (self): #以下两个方法实现切片的序列
Return Len (self._components)
def __getitem__ (self, item):
CLS = Type (self) #获取实例的类 for later use
If Isinstance (item,slice):
Return CLS (Self._components[item])
Elif isinstance (item,numbers. Integral):
return Self._components[item]
Else
msg = ' {cls.__name__} indices must be integers '
Raise TypeError (Msg.format (CLS=CLS))
def __eq__ (self, Other):
Return Len (self) = = Len (other) and all (A==b for a, b in zip (self,other)) #all函数, the result is false whenever the result of a comparison is false. All results are true, Result is True
#考虑到, according to the old rules, the comparison between Vector ([up]) and () is the same, so the new rule comes out.
def __hash__ (self):
hashes = Map (hash,self._components)
Return Functools.reduce (operator.xor,hashes)
def angle (self,n):
r = math.sqrt (sum (x*x for x in Self[n:]))
A = Math.atan2 (r,self[n-1])
if (n = = Len (self)-1) and (Self[-1] < 0):
Return math.pi*2-a
Else
Return a
def angles (self):
Return (Self.angle (n) for n in range (1,len (self))
def __format__ (self, Fmt_spec):
If Fmt_spec.endswith (' H '):
Fmt_spec = Fmt_spec[:-1]
coords = Itertools.chain ([ABS (self)],self.angles ())
A = List (Self.angles ())
outer_fmt = ' <{}> '
Else
coords = Self
Outer_fmt = ' ({}) '
components = (format (C,FMT_SPEC) for C in coords)
Return Outer_fmt.format (', '. Join (components))

#通过 @property to get the property dynamically, want to get the four components of the vector, to write four such a feature, too cumbersome, so choose __getattr__ this special method.
#属性查找失败后, the interpreter invokes the __getattr__ method. In simple terms, for my_obj.x expressions, Python checks that the My_obj instance has no attribute named X, and if not, finds it in the class (my_obj.__class__) and, if not, continues to find it along the inheritance tree. If it is still not found, call MY_OBJH in the class that belongs to
#... Defines the __getattr__ method, passed in as a string of self and property names.
#例子10-8
Shortcut_names = ' Xyzt '
def __getattr__ (self, item):
CLS = Type (self)
If Len (item) = = 1:
pos = Cls.shortcut_names.find (item)
If 0<= Pos < Len (self._components):
return Self._components[pos]
msg = ' {. __name__!r} object has no attribute {!r} '
Raise Attributeerror (Msg.format (Cls,item))



# "Notes" 1?? The way to use REPRLIB.REPR requires some clarification. This function is used to generate a secure representation of a large data structure or recursive structure, which restricts the length of the output string and uses the ' ... ' to denote the truncated part. I want the vector instance to behave like a vector ([3.0,4.0]), rather than
#Vector (Array (' d ', [3.0,4.0])) because we do not need implementation details in the instance.
# "Notes" 2?? When writing the __repr__ method, you can use this expression to generate a simplified componets display: Reprlib.repr (List (self._components)). However, it is wasteful to do so because you want to copy each element in the self._components with a list,
#然后使用列表的表示形式.
# "Notes" 3?? Call Repr () is intended to debug
# "Notes" 4?? We could have let the vector inherit the vector2d, not the reason for the baby. First, two construction methods are incompatible, so inheritance is not recommended. This can be solved by properly handling the parameters of the __init__ method, but the second reason is more important: I want to use the vector class as a separate case to implement the sequence protocol

#10.3 protocol and Duck type

‘‘‘
#例子10-3 slices of the series that can be sliced
V7 = Vector (range (7))
Print (V7[-1]) #6.0
Print (V7[1:4]) #Vector ([1.0, 2.0, 3.0])
Print (v7[-1:]) #Vector ([6.0])
Print (v7[1,2]) #TypeError: vector indices must be integers vector does not support multidimensional indexing

#例子10-4 Learn about the behavior of __getitem__ and slices
Class Myseq:
def __getitem__ (self, item):
Return item
s = Myseq ()
Print (s[1]) #1
Print (S[1:4]) #slice (1, 4, None)
Print (S[1:4:2]) #slice (1, 4, 2)
Print (s[1:4:2,9]) # (Slice (1, 4, 2), 9)
Print (S[1:4:2,7:9]) # (Slice (1, 4, 2), Slice (7, 9, None))
#例子10-5 View slice Properties
Print (slice) #<class ' slice ' >
Print (dir (slice))
Print (Slice (none,10,2). Indices (5)) # (0, 5, 2)
Print (' ABCDE ' [: 10:2]) #ACE According to the above principle, equivalent to ' ABCDE ' [0:5:2]
Print (Slice ( -3,none,none). Indices (5)) # (2, 5, 1)
Print (' ABCDE ' [-3:]) #CDE equivalent to ' ABCDE ' [2:5:1]

#例子10 the use of -15 zip built-in functions
Print (Zip (range (3), ' ABC ')) #<zip object at 0x102832788>
Print (List (Zip (range (3), ' ABC ')) #[(0, ' A '), (1, ' B '), (2, ' C ')]
Print (List (Zip (range (3), ' ABC ', [0.0,1.1,2.2,3.3])) #[(0, ' A ', 0.0), (1, ' B ', 1.1), (2, ' C ', 2.2)] zip has a strange feature when an iterative object is exhausted , it stops without warning
From Itertools import zip_longest
Print (List (Zip_longest (range (3), ' ABC ', [0.0,1.1,2.2,3.3],fillvalue=-1))] #[(0, ' A ', 0.0), (1, ' B ', 1.1), (2, ' C ', 2.2), ( -1,-1, 3.3)]

Print (', '. Join (Format (c, '. 3e ') for C in (3.45678,0.555555))) #3.457e+00,5.556e-01
Print (' {:. 3e},{:.3e} '. Format (3.4567855,0.555555)) #3.457e+00,5.556e-01
Import Itertools
Print (Itertools.chain (' 123 ', ' 456 ')) #<itertools.chain object at 0x10c554c18>
Print (List (Itertools.chain (' 123 ', ' 456 ')) # [' 1 ', ' 2 ', ' 3 ', ' 4 ', ' 5 ', ' 6 ']
Print (List (Itertools.chain ([3.4444], (3.4444444,))) #[3.4444, 3.4444444]
#tests of ' format () ' with spherical coordinates in 2D,3D and 4d:
V3 = Vector ([+])
Print (Format (v3, ' h ')) #<1.4142135623730951,0.7853981633974483>
Print (Format (v3, '. 3eh ')) #<1.414e+00,7.854e-01>
Print (Format (v3, ' 0.5fh ')) #<1.41421,0.78540>
V4 = Vector ([1,1,1])
Print (Format (v4, ' h ')) #<1.7320508075688772,0.9553166181245093,0.7853981633974483>
V5 = Vector ([ -1,-1,-1,-1])
Print (Format (V5, '. 3eh ')) #<2.000e+00,2.094e+00,2.186e+00,3.927e+00>
#tests of ' format () ' with Cartesian coordinates in 2d:
V5 = Vector ([3,4])
Print (Format (V5)) # (3.0,4.0)
Print (Format (V5, '. 2f ')) # (3.00,4.00)
Print (Format (V5, '. 3e ')) # (3.000E+00,4.000E+00)
#tests of ' format () ' with Cartesian coordinates in 3d and 7d:
V6 = Vector ([3,4,5])
Print (Format (V6))
V7 = Vector (range (7)) # (3.0,4.0,5.0)
Print (Format (V7)) # (0.0,1.0,2.0,3.0,4.0,5.0,6.0)
#tests of hashing
V9 = Vector ([3,4])
V10 = Vector (range (6)) #7 1
Print (hash (v9), hash (V10))
#Most hash values on ono-integers vary from a 32-bit to 64-bit CPython build::
Import Sys
V8 = Vector ([3.1,4.2])
Print (hash (V8)) #384307168202284039
Print (hash (v8) = = (384307168202284039 if sys.maxsize > 2**32 else 357915986)) #True
#tests of '. __bytes__ ' and ' frombytes () ' methods:
V11 = Vector ([3,4,5])
V11_clone = vector.frombytes (bytes (v11))
Print (V11_clone) #Vector ([3.0, 4.0, 5.0])
Print (V11 = = V11_clone) #True

# example 10-9 For example 10-8 validation, inappropriate behavior: for v.x assignment no error, but inconsistent
V12 = Vector (range (5))
Print (v12) #Vector ([0.0, 1.0, 2.0, 3.0, 4.0])
Print (v12.x) #0.0
v12.x = 10
Print (v12.x) #10
Print (v12) #为向量赋新值后, the vector remains the same. Vector ([0.0, 1.0, 2.0, 3.0, 4.0])
# "Parse" If there is no new value in the component array of the vector, why v12.x returns 10? Example 10-9 the paradox is caused by the way the __getattr__ works: Python calls that method only if the object does not have a property of the specified name, which is a fallback mechanism. But, like v12.x=10, it's an assignment.
#... After the assignment, the V12 object has an X attribute, so the __getattr__ method is not called when the value of the V12.xhuoqu x property is used, and the interpreter returns the value bound to v12.x directly, which is 10. To avoid this paradox, we want to rewrite the logic of setting properties in vectors.
#例子10-10 Implement the __setter__ method: Although this example does not support assigning a value to vector components, there is one problem to pay special attention to: most of the time, if the-__getattr__ method is implemented, then the __SETATTR__ method is implemented, In case the object behaves inconsistent.
#如果像允许修改分量, you can use __setitem__ for vectors, support v[0]=1.1, or implement __setattr__ to support v.x=1.1. However, we want to keep the vector immutable, because the next experiment we're going to turn it into a hash.
#这里格外讲一下__setattr__
Class Test:
Shortcut_names = ' Xyzt '
def __setattr__ (self, Key, value):
CLS = Type (self)
If Len (key) = = 1:
If key in Cls.shortcut_names:
Error = ' readonly attribute {attr_name!r} '
Elif Key.islower ():
Error = "Cannot set attribute ' a ' to ' Z ' in {cls_name!r}"
Else
Error = '
If error:
msg = Error.format (Cls_name=cls,attr_name=key)
Raise Attributeerror (MSG)
Super (). __setattr__ (Key,value)
V11 = Test ()
#v11. x = 2 #AttributeError: readonly attribute ' x '
#v11. A = 3 #AttributeError: Cannot set attribute ' a ' to ' Z ' in <class ' __main__. Test ' >
V11. B = 3
Print (v11. B) #3
# "Analysis"
#1?? To select the error message for Attributeerror, I looked at the behavior of the built-in complex type because the complex object is immutable and has a bunch of data properties: Real imag. If you attempt to modify any of the properties, the complex instance throws Attributeerror, and the error
#消息设置为 "Cannot set attribute". If you try to assign a value to a protected read-only property, the resulting error message is ' readonly attribute '. When I select a word for the error string in the __setattr__ method, I refer to these two error messages
#注意, we are not forbidden to assign a value to all attributes, only to prohibit assigning a value to a single lowercase attribute, in case of being confused with a read-only attribute x y z t
#2?? We know that the __slots__ property in the type declaration prevents the setting of new instance properties; Therefore, you might want to use this feature instead of implementing the __setattr__ method, as you did here. However, it is not intended to be used only to avoid creating instance properties. The __slots__ property should only be used to conserve memory, and only when memory is critically low
‘‘‘
























































"Python" "Xulie ' update&sanlie&cisling.py"

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.