-
Notifications
You must be signed in to change notification settings - Fork 0
/
clojure_characters.txt
652 lines (467 loc) · 24.8 KB
/
clojure_characters.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
This page explains the Clojure syntax for characters that are difficult to "google". Sections are not in any particular order, but related items are grouped for ease. Please refer to the reader reference page as the authoritative reference on the Clojure reader. This guide is based on James Hughes original blog post and has been updated and expanded here with the permission of the author.
( … ) - List
Lists are sequential heterogeneous collections implemented as a linked list.
Clojure Documentation: Lists
A list of three values:
(1 "two" 3.0)
[ … ] - Vector
Vectors are sequential, indexed, heterogeneous collections. Indexing is 0-based.
An example of retrieving the value at index 1 in a vector of three values:
user=> (get ["a" 13.7 :foo] 1)
13.7
Clojure Documentation: Vectors
{ … } - Map
Maps are heterogeneous collections specified with alternating keys and values:
user=> (keys {:a 1 :b 2})
(:a :b)
Clojure Documentation: Maps
# - Dispatch character
You’ll see this character beside another e.g. #( or #".
# is a special character that tells the Clojure reader (the component that takes Clojure source and "reads" it as Clojure data) how to interpret the next character using a read table. Although some Lisps allow the read table to be extended by users, Clojure does not.
The # is also used at the end of a symbol when creating generated symbols inside a syntax quote.
#{ … } - Set
See # for additional details.
#{…} defines a set (a collection of unique values), specifically a hash-set. The following are equivalent:
user=> #{1 2 3 4}
#{1 2 3 4}
user=> (hash-set 1 2 3 4)
#{1 2 3 4}
Sets cannot contain duplicates and thus the set reader will throw an exception in this case as it is an invalid literal. When items are added to a set, they are simply dropped if the value is already present.
user=> #{1 2 3 4 1}
IllegalArgumentException Duplicate key: 1 clojure.lang.PersistentHashSet.createWithCheck (PersistentHashSet.java:68)
Clojure Documentation: Sets
#_ - Discard
See # for additional details.
#_ tells the reader to ignore the next form completely.
user=> [1 2 3 #_ 4 5]
[1 2 3 5]
Note that the space following #_ is optional, so
user=> [1 2 3 #_4 5]
[1 2 3 5]
also works. Also note that the discard character works in edn.
A neat trick is that multiple #_ can be stacked to omit multiple forms
user=> {:a 1, #_#_ :b 2, :c 3}
{:a 1, :c 3}
The docs suggest that "The form following #_ is completely skipped by the reader (This is a more complete removal than the comment macro which yields nil).". This can prove useful for debugging situations or for multiline comments.
Clojure Documentation - Reader
edn Tagged Elements
#"…" - Regular Expression
See # for additional details.
#" indicates the start of a regular expression
user=> (re-matches #"^test$" "test")
"test"
This form is compiled at read time into a host-specific regex machinery, but it is not available in edn. Note that when using regexes in Clojure, Java string escaping is not required
Clojure Documentation: Regex Support
Java Regex
#(…) - Anonymous function
See # for additional details.
#( begins the short hand syntax for an inline function definition. The following two snippets of code are similar:
; anonymous function taking a single argument and printing it
(fn [line] (println line))
; anonymous function taking a single argument and printing it - shorthand
#(println %)
The reader expands an anonymous function into a function definition whose arity (the number of arguments it takes) is defined by how the % placeholders are declared. See the % character for discussion around arity.
user=> (macroexpand `#(println %))
(fn* [arg] (clojure.core/println arg)) ; argument names shortened for clarity
#' - Var quote
#' is the var quote which expands into a call to the var function:
user=> (read-string "#'foo")
(var foo)
user=> (def nine 9)
#'user/nine
user=> nine
9
user=> (var nine)
#'user/nine
user=> #'nine
#'user/nine
When used it will attempt to return the referenced var. This is useful when you want to talk about the reference/declaration instead of the value it represents. See the use of meta in the metadata (^) discussion.
Note that var quote is not available in edn.
Clojure Official Documentation: Special Forms
## - Symbolic values
Clojure can read and print the symbolic values ##Inf, ##-Inf, and ##NaN. These are also available in edn.
user=> (/ 1.0 0.0)
##Inf
user=> (/ -1.0 0.0)
##-Inf
user=> (Math/sqrt -1.0)
##NaN
#inst, #uuid, and #js etc. - tagged literals
Tagged literals are defined in edn and supported by the Clojure and ClojureScript readers natively. The #inst and #uuid tags are defined by edn, whereas the #js tag is defined by ClojureScript.
We can use Clojure’s read-string to read a tagged literal (or use it directly):
user=> (type #inst "2014-05-19T19:12:37.925-00:00")
java.util.Date ;; this is host dependent
(read-string "#inst \"2014-05-19T19:12:37.925-00:00\"")
#inst "2014-05-19T19:12:37.925-00:00"
A tagged literal tells the reader how to parse the literal value. Other common uses include #uuid for expressing UUIDs and in the ClojureScript world an extremely common use of tagged literals is #js which can be used to convert ClojureScript data structures into JavaScript structures directly. Note that #js doesn’t convert recursively, so if you have a nested data-structure, use js->clj.
Note that while #inst and #uuid are available in edn, #js is not.
edn Tagged Elements
%, %n, %& - Anonymous function arguments
% is an argument in an anonymous function (…) as in (* % %).
When an anonymous function is expanded, it becomes an fn form and % args are replaced with gensym’ed names (here we use arg1, etc for readability):
user=> (macroexpand `#(println %))
(fn* [arg1] (clojure.core/println arg1))
Numbers can be placed directly after the % to indicate the argument positions (1-based). Anonymous function arity is determined based on the highest number % argument.
user=> (macroexpand `#(println %1 %2))
(fn* [arg1 arg2] (clojure.core/println arg1 arg2)) ; takes 2 args
user=> (macroexpand `#(println %4))
(fn* [arg1 arg2 arg3 arg4] (clojure.core/println arg4)) ; takes 4 args doesn't use 3
You don’t have to use the arguments, but you do need to declare them in the order you’d expect an external caller to pass them in.
% and %1 can be used interchangeably:
user=> (macroexpand `#(println % %1)) ; use both % and %1
(fn* [arg1] (clojure.core/println arg1 arg1)) ; still only takes 1 argument
There is also %& which is the symbol used in a variadic anonymous function to represent the "rest" of the arguments (after the highest named anonymous argument).
user=> (macroexpand '#(println %&))
(fn* [& rest__11#] (println rest__11#))
Anonymous functions and % are not part of edn.
@ - Deref
@ expands into a call to the deref function, so these two forms are the same:
user=> (def x (atom 1))
#'user/x
user=> @x
1
user=> (deref x)
1
user=>
@ is used to get the current value of a reference. The above example uses @ to get the current value of an atom, but @ can be applied to other things such as future s, delay s, promises s etc. to force computation and potentially block.
Note that @ is not available in edn.
^ (and #^) - Metadata
^ is the metadata marker. Metadata is a map of values (with shorthand option) that can be attached to various forms in Clojure. This provides extra information for these forms and can be used for documentation, compilation warnings, typehints, and other features.
user=> (def ^{:debug true} five 5) ; meta map with single boolean value
#'user/five
We can access the metadata by the meta function which should be executed against the declaration itself (rather than the returned value):
user=> (def ^{:debug true} five 5)
#'user/five
user=> (meta #'five)
{:ns #<Namespace user>, :name five, :column 1, :debug true, :line 1, :file "NO_SOURCE_PATH"}
As we have a single value here, we can use a shorthand notation for declaring the metadata ^:name which is useful for flags, as the value will be set to true.
user=> (def ^:debug five 5)
#'user/five
user=> (meta #'five)
{:ns #<Namespace user>, :name five, :column 1, :debug true, :line 1, :file "NO_SOURCE_PATH"}
Another use of ^ is for type hints. These are used to tell the compiler what type the value will be and allow it to perform type specific optimizations thus potentially making resultant code faster:
user=> (def ^Integer five 5)
#'user/five
user=> (meta #'five)
{:ns #<Namespace user>, :name five, :column 1, :line 1, :file "NO_SOURCE_PATH", :tag java.lang.Integer}
We can see in that example the :tag property is set.
You can also stack the shorthand notations:
user=> (def ^Integer ^:debug ^:private five 5)
#'user/five
user=> (meta #'five)
{:ns #<Namespace user>, :name five, :column 1, :private true, :debug true, :line 1, :file "NO_SOURCE_PATH", :tag java.lang.Integer}
Originally, meta was declared with #^, which is now deprecated (but still works). Later, this was simplified to just ^ and that is what you will see in most Clojure, but occasionally you will encounter the #^ syntax in older code.
Note that metadata is available in edn, but type hints are not.
Clojure Official Documentation
Learning Clojure: Meta Data
' - Quote
Quoting is used to indicate that the next form should be read but not evaluated. The reader expands ' into a call to the quote special form.
user=> (1 3 4) ; fails as it tries to invoke 1 as a function
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn user/eval925 (NO_SOURCE_FILE:1)
user=> '(1 3 4) ; quote
(1 3 4)
user=> (quote (1 2 3)) ; using the longer quote method
(1 2 3)
user=>
Clojure Special Forms
; - Comment
; starts a line comment and ignores all input from its starting point to the end of the line.
user=> (def x "x") ; this is a comment
#'user/x
user=> ; this is a comment too
<returns nothing>
It is common in Clojure to use multiple semicolons for readability or emphasis, but these are all the same to Clojure
;; This is probably more important than
; this
: - Keyword
: is the indicator for a keyword. Keywords are often used as keys in maps and they provide faster comparisons and lower memory overhead than strings (because instances are cached and reused).
user=> (type :test)
clojure.lang.Keyword
Alternatively you can use the keyword function to create a keyword from a string
user=> (keyword "test")
:test
Keywords can also be invoked as functions to look themselves up as a key in a map:
user=> (def my-map {:one 1 :two 2})
#'user/my-map
user=> (:one my-map) ; get the value for :one by invoking it as function
1
user=> (:three my-map) ; it can safely check for missing keys
nil
user=> (:three my-map 3) ; it can return a default if specified
3
user => (get my-map :three 3) ; same as above, but using get
3
Data Structures - Keywords
:: - Auto-resolved keyword
:: is used to auto-resolve a keyword in the current namespace. If no qualifier is specified, it will auto-resolve to the current namespace. If a qualifier is specified, it may use aliases in the current namespace:
user=> :my-keyword
:my-keyword
user=> ::my-keyword
:user/my-keyword
user=> (= ::my-keyword :my-keyword)
false
This is useful when creating macros. If you want to ensure that a macro that calls another function in the macro namespace correctly expands to call the function, you could use ::my-function to refer to the fully qualified name.
Note that :: is not available in edn.
Reader
#: and #:: - Namespace Map Syntax
Namespace map syntax was added in Clojure 1.9 and is used to specify a default namespace context for keys in a map, where those keywords (or symbols) share a common namespace.
#:: can be used to auto-resolve the namespace of keyword or symbol keys in a map using the current namespace.
These two examples are equivalent:
user=> (keys {:user/a 1, :user/b 2})
(:user/a :user/b)
user=> (keys #::{:a 1, :b 2})
(:user/a :user/b)
Similar to autoresolved keywords, you can also specify an alias in the namespace map prefix with #:ns prefix, where ns is the name of a namespace and the prefix precedes the opening brace { of the map.
For example, the following map literal with namespace syntax:
#:person{:first "Han"
:last "Solo"
:ship #:ship{:name "Millennium Falcon"
:model "YT-1300f light freighter"}}
is read as:
{:person/first "Han"
:person/last "Solo"
:person/ship {:ship/name "Millennium Falcon"
:ship/model "YT-1300f light freighter"}}
Reader
/ - Namespace separator
/ can be the division function clojure.core//, but can also act as a separator in a symbol name to separate a symbol’s name and namespace qualifier, e.g. my-namespace/utils. Namespace qualifiers can thus prevent naming collisions for simple names.
Reader
\ - Character literal
\ indicates a literal character as in:
user=> (str \h \i)
"hi"
There are also a small number of special characters to name special ASCII characters: \newline, \space, \tab, \formfeed, \backspace, and \return.
The \ can also be followed by a Unicode literal of the form \uNNNN. For example, \u03A9 is the literal for Ω.
$ - Inner class reference
Used to reference inner classes and interfaces in Java. Separates the container class name and the inner class name.
(import (basex.core BaseXClient$EventNotifier)
(defn- build-notifier [notifier-action]
(reify BaseXClient$EventNotifier
(notify [this value]
(notifier-action value))))
EventNotifier is an inner interface of the BaseXClient class which is an imported Java class
Clojure: Using Java Inner Classes
Official Documentation
->, ->>, some->, cond->, as-> etc. - Threading macros
These are threading macros. Please refer to Official Clojure Documentation
Understanding the Clojure -> macro
` - Syntax quote
` is the syntax quote. Syntax quote is similar to quoting (to delay evaluation) but has some additional effects.
Basic syntax quote may look similar to normal quoting:
user=> (1 2 3)
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn user/eval832 (NO_SOURCE_FILE:1)
user=> `(1 2 3)
(1 2 3)
However, symbols used within a syntax quote are fully resolved with respect to the current namespace:
user=> (def five 5)
#'user/five
user=> `five
user/five
Syntax quote is most used as a "template" mechanism within macros. We can write one now:
user=> (defmacro debug [body]
#_=> `(let [val# ~body]
#_=> (println "DEBUG: " val#)
#_=> val#))
#'user/debug
user=> (debug (+ 2 2))
DEBUG: 4
4
Macros are functions invoked by the compiler with code as data. They are expected to return code (as data) that can be further compiled and evaluated. This macro takes a single body expression and returns a let form that will evaluate the body, print its value, and then return the value. Here the syntax quote creates a list, but does not evaluate it. That list is actually code.
See ~@ and ~ for additional syntax allowed only within syntax quote.
Clojure for the Brave and True - Writing Macros
Clojure from the ground up: macros
Clojure Official Documentation
~ - Unquote
See ` for additional information.
~ is unquote. That is within a syntax quoted ` form ~ will unquote the associated symbol, i.e. evaluate it in the current context:
user=> (def five 5) ; create a named var with the value 5
#'user/five
user=> five ; the symbol five is evaluated to its value
5
user=> `five ; syntax quoting five will avoid evaluating the symbol, and fully resolve it
user/five
user=> `~five ; within a syntax quoted block, ~ will turn evaluation back on just for the next form
5
Syntax quoting and unquote are essential tools for writing macros, which are functions invoked during compilation that take code and return code.
Clojure for the Brave and True - Writing Macros
Clojure from the ground up: macros
Clojure Official Documentation
~@ - Unquote splicing
See ` and ~ for additional information.
~@ is unquote-splicing. Where unquote (~) evaluates a form and places the result into the quoted result, ~@ expects the evaluated value to be a collection and splices the contents of that collection into the quoted result.
user=> (def three-and-four (list 3 4))
#'user/three-and-four
user=> `(1 ~three-and-four) ; evaluates `three-and-four` and places it in the result
(1 (3 4))
user=> `(1 ~@three-and-four) ; evaluates `three-and-four` and places its contents in the result
(1 3 4)
Again, this is a powerful tool for writing macros.
Clojure for the Brave and True - Writing Macros
Clojure from the ground up: macros
Clojure Official Documentation
<symbol># - Gensym
A # at the end of a symbol is used to automatically generate a new symbol. This is useful inside macros to keep macro specifics from leaking into the userspace. A regular let will fail in a macro definition:
user=> (defmacro m [] `(let [x 1] x))
#'user/m
user=> (m)
CompilerException java.lang.RuntimeException: Can't let qualified name: user/x, compiling:(NO_SOURCE_PATH:1)
This is because symbols inside a syntax quote are fully resolved, including the local binding x here.
Instead you can append # to the end of the variable name and let Clojure generate a unique (unqualified) symbol:
user=> (defmacro m [] `(let [x# 1] x#))
#'user/m
user=> (m)
1
user=>
Importantly, every time a particular x# is used within a single syntax quote, the same generated name will be used.
If we expand this macro, we can see the gensym 'd name:
user=> (macroexpand '(m))
(let* [x__681__auto__ 1] x__681__auto__)
ClojureDocs - gensyms
#? - Reader conditional
Reader conditionals are designed to allow different dialects of Clojure to share common code. The reader conditional behaves similarly to a traditional cond. The syntax for usage is #? and looks like this:
#?(:clj (Clojure expression)
:cljs (ClojureScript expression)
:cljr (Clojure CLR expression)
:default (fallthrough expression))
Reader conditonals
#?@ - Splicing Reader conditional
The syntax for a splicing reader conditional is #?@. It is used to splice lists into the containing form. So the Clojure reader would read this:
(defn build-list []
(list #?@(:clj [5 6 7 8]
:cljs [1 2 3 4])))
as this:
(defn build-list []
(list 5 6 7 8))
Reader conditonals
*var-name* - "Earmuffs"
Earmuffs (a pair of asterisk bookending var names) is a naming convention in many LISPs used to denote special vars. Most commonly in Clojure this is used to denote dynamic vars, i.e. ones that can change depending on dynamic scope. The earmuffs act as a warning that "here be dragons" and to never assume the state of the var. Remember, this is a convention, not a rule.
Core Clojure examples include *out* and *in* which represent the standard in and out streams for Clojure.
How is the var-name naming-convention used in clojure?
Clojure API Docs
>!!, <!!, >!, and <! - core.async channel macros
These symbols are channel operations in core.async - a Clojure/ClojureScript library for channel based asynchronous programming (specifically CSP - Communicating Sequential Processes).
If you imagine, for the sake of argument, a channel is a bit like a queue that things can put stuff on and take stuff off, then these symbols support that simple API.
>!! and <!! are blocking put and take respectively
>! and <! are, simply put and take
THe difference being the blocking version operate outside go blocks and block the thread they operate on.
user=> (def my-channel (chan 10)) ; create a channel
user=> (>!! my-channel "hello") ; put stuff on the channel
user=> (println (<!! my-channel)) ; take stuff off the channel
hello
The non-blocking versions need to be executed within a go block, otherwise they’ll throw an exception.
user=> (def c (chan))
#'user/c
user=> (>! c "nope")
AssertionError Assert failed: >! used not in (go ...) block
nil clojure.core.async/>! (async.clj:123)
While the difference between these is well outside the scope of this guide, fundamentally the go blocks operate and manage their own resources pausing execution of code without blocking threads. This makes asynchronously executed code appear to be synchronous, removing the pain of managing asynchronous code from the code base.
core.async Code Walkthrough
core.async Wiki
Go Block Best Practices
<symbol>? - Predicate Suffix
Putting ? at the end of a symbol is a naming convention common across many languages that support special characters in their symbol names. It is used to indicate that the thing is a predicate, i.e. that it poses a question. For example, imagine using an API that dealt with buffer manipulation:
(def my-buffer (buffers/create-buffer [1 2 3]))
(buffers/empty my-buffer)
At a glance, how would you know if the function empty in this case,
Returned true if the passed in buffer was empty, or,
Cleared the buffer
While the author could have renamed empty to is-empty, the richness of symbol naming in Clojure allows us to express intent more symbolically.
(def my-buffer (buffers/create-buffer [1 2 3]))
(buffers/empty? my-buffer)
false
This is simply a recommended convention, not a requirement.
Clojure Style Guide
<symbol>! - Unsafe Operations
The Clojure style guide has this to say:
The names of functions/macros that are not safe in STM transactions should end with an exclamation mark (e.g reset!).
You’ll most commonly see this appended to function names whose purpose is to mutate state, e.g. connecting to a data store, updating an atom or closing a file stream
user=> (def my-stateful-thing (atom 0))
#'user/my-stateful-thing
user=> (swap! my-stateful-thing inc)
1
user=> @my-stateful-thing
1
This is simply a recommended convention and not a requirement.
Note that the exclamation mark is often pronounced as bang.
Clojure Style Guide
_ - Unused argument
When you see the underscore character used as function arguments or in a let binding, _ is a common naming convention to indicate you won’t be using this argument.
This is an example using the add-watch function that can be used to add callback style behaviour when atoms change value. Imagine, given an atom, we want to print the new value every time it changes:
(def value (atom 0))
(add-watch value nil (fn [_ _ _ new-value]
(println new-value))
(reset! value 6)
; prints 6
(reset! value 9)
; prints 9
add-watch takes four arguments, but in our case we only really care about the last argument - the new value of the atom so we use _ for the others.
, - Whitespace character
In Clojure, , is treated as whitespace, exactly the same as spaces, tabs, or newlines. Commas are thus never required in literal collections, but are often used to enhance readability:
user=>(def m {:a 1, :b 2, :c 3}
{:a 1, :b 2, :c 3}
#= Reader eval
#= allows the reader to evaluate an arbitrary form during read time:
user=> (read-string "#=(+ 3 4)")
;;=> 7
#=123
;;=> 123
#="foo"
;;=> foo
(def foo 1)
#='foo
;;=> 1
Note that the read-time evaluation can also cause side-effects:
user=> (read-string "#=(println :foo)")
:foo
nil
Consequently, read-string is not safe to call with unverified user input. For a safe alternative, see clojure.edn/read-string.
Note that #= is not an officially supported feature of the reader, so you shouldn’t rely on its presence in future versions of Clojure.
Many thanks to everyone who has contributed ideas and [the copious amounts of] spelling corrections (crikey I’m bad at speelingz - so thanks Michael R. Mayne, lobsang_ludd). I’ve tried to call out people who have specifically asked for things. Sorry if I’ve missed you.
Original author: James Hughes
Python numbers.
Python 3 has a slightly different representation:
>>> p = 0o1212
>>> print (p)
650
>>> print (oct(p))
0o1212
Use the format() function with a '02x' format.
>>> format(255, '02x')
'ff'
>>> format(2, '02x')
'02'
The 02 part tells format() to use at least 2 digits and to use zeros to pad it to length, x means lower-case hexadecimal.
The Format Specification Mini Language also gives you X for uppercase hex output, and you can prefix the field width with # to include a 0x or 0X prefix (depending on wether you used x or X as the formatter). Just take into account that you need to adjust the field width to allow for those extra 2 characters:
>>> format(255, '02X')
'FF'
>>> format(255, '#04x')
'0xff'
>>> format(255, '#04X')
'0XFF'
# First set the variable named value = to the decimal number 127
>>> value = 127
# displaying the number in hex as you would suspect is as easy and saying
# show me the hex representation of the variable “value”. using the proper syntax of course
>>> hex(value)
‘0x7f’
# I like to see my hex numbers in all caps, I know old school
# so I add on the upper() function as shown below
>>> hex(value).upper()
‘0X7F’
#displaying the number in binary works the same way
>>> bin(value)
‘0b1111111’
>>>
# what if we want to “Exclusive Or” two hex values together?
# we first set variable A = to a hex 20 and variable B = to a hex 40
>>> A = 0x20
>>> B = 0x40
# then we use the carrot operator to create the new variable C
# (this operator represents “Exclusive Or” in most languages)
>>> C = A ^ B
# then we use the hex function once again to display the result
>>> hex(C).upper()
‘0X60’
# and of course we then would like to display the variable C in binary
>>> bin(C)
‘0b1100000’