Пространства имён и простейшие операторы
Компилируемый язык – это язык программирования, исходный код которого преобразуется компилятором в машинный код и записывается в файл. Формат этого файла отличен от формата файла с программой. Главное преимущество компилируемых языков — это скорость исполнения.
Интерпретируемый язык – это язык программирования, в котором исходный код не преобразуется в машинный код для выполнения центральным процессором, а исполняется с помощью интерпретатора. Преимущество заключается в том, что код всегда доступен для чтения, и его можно легко изменить. В случае со скомпилированным кодом нужно найти, где находится код, изменить его, скомпилировать и заново запустить программу. Почти всегда анализ собственной программы более простой (не по синтаксису). Дело в том, что анализ происходит только на этапе лексического анализа. Что лексемы значат понять нельзя. Наличие объекта в недрах интерпретатора – это понятие динамическое. Тип объекта тоже динамическое понятие.
>>> asdf=234 >>> type(asdf) <class 'int'> >>> asdf="sdfg" >>> type(asdf) <class 'str'> >>>
На этом примере убедимся, что нельзя предсказать, как и что будет выполняться.
>>> a,b = 2,3 >>> a*b 6 >>> b = "QWE" >>> a*b 'QWEQWE' >>> >>> a = "asd" >>> a*b Traceback (most recent call last): File "<pyshell#10>", line 1, in <module> a*b TypeError: can't multiply sequence by non-int of type 'str' >>>
Замечание: иногда Python не типизированный.
>>> type(type) <class 'type'> >>> type(int) <class 'type'> >>>
Мы знаем, что все объекты имеют уникальный идентификатор.
>>> id(asdf) 54398176 >>> asdf 'sdfg' >>> c=d=asdf >>> id(c) 54398176 >>>
Некоторые типы в Python
- int
- float
- complex
- bool (Булев тип)
- Строковый тип
- None
У типа None существует только один экземпляр, и он не выводится
>>> type(None) <class 'NoneType'> >>> None >>>
Замечание: числовые типы имеют произвольную размерность
Поговорим о пространстве имен
Мы уже знаем про dir().
В этом пространстве имен замечаем и свои имена и системные имена(специальные имена), с которыми познакомимся позже.
В возвращаемом функцией dir() списке не содержится встроенных функций и переменных. Если вы хотите получить их список, то они определены в стандартном модуле builtins.
>>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'asdf', 'b', 'c'] >>> dir(__builtins__) ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip'] >>>
Любой объект – это пространство имен.
Следует обратить внимание на понятие инкапсуляция. Инкапсуляция – это способ организовать иерархическое пространство имен.
>>> a=123 >>> a.imag 0 >>> 123.imag File "<stdin>", line 1 123.imag ^ SyntaxError: invalid syntax >>> (123).imag 0 >>>
>>(123).imag – это отсылка к инкапсуляции.
Имена, заключенные в объекты, не отличаются от имен в пространстве имен.
>>> a=123 >>> a.bit_length() 7 >>> a 123 >>> a.__add__(100500) 100623 >>>
Поля объекта называются полями, а некоторые методами.
>>> a = 234234 >>> type(a) is str False >>>
Когда мы связываем объект, у связи нет типа. Мы можем написать код, который будет проверять. Но синтаксической проверки нет вообще. Любая конструкция синтаксически правильная. Любой метод применим к любым данным. Любая структура данных состоит из любых объектов.
Важное свойство: неявная динамическая типизация.
Про конструкции языка Python
>>> a,b=3,4 >>> a==b False >>> a is b False >>> a<=b True >>> a>=b False >>> a,b,c,d=1,3,56,78 >>> a<b<c<d True >>>
>>> True < 0.5 False >>>
Т.к. True < 0.5 все равно, что 1 < 0.5.
Еще одно важное свойство - это порядок выполнения логических операций. Пример
>>> (1 == 1) or (1/0 == 5) True >>> (1 != 1) and (1/0 == 5) False >>>
В этих двух случаях не возникают ошибки при делении на 0, т.к. операция деления вообще не будет выполнена. Это связано с тем, что сначала вычисляется первый операнд (1 == 1) и принимает значение True. Далее второй операнд не будет вычисляться, т.к. для операции or он не имеет значения: первый операнд True => True or 'что угодно' == True. Аналогичная ситуация с and.
>>> a,b,c,d=0.1,0.2,0.4,0.7 >>> a<b<c<d True >>> True < 0.4 False >>> a<b<c True >>> (a<b)<c False >>> (a<b) and (b<c) True >>> 1 in [1,2,3] True >>> 1 in [11,12,13] False >>> False in [False] True >>> False is [False] False >>> False is False True >>> False is False in [False] True >>>
В Python любой объект может быть логическим выражением
Примеры:
>>> not 234 False >>> not 0 True >>> not "SDF" False >>> not [1,2,3] False >>>
>>> a,b="qwe",123 >>> a and b 123 >>> a,b = "qwe", [] >>> a and b [] >>>
Поговорим про eval
>>> eval <built-in function eval> >>> a="1,2,3" >>> a '1,2,3' >>> type(a) <class 'str'> >>> eval(a) (1, 2, 3) >>> a,d,e=eval(a) >>> a 1 >>> d 2 >>> e 3 >>> a="d+8" >>> a 'd+8' >>> eval(a) 10 >>>
Напишем программу
a,b = eval(input("Введите: ")) if a>b: print("Больше") else: if a<b: print("Меньше") print("Честно!") else: print("Равно")
Важная особенность языка Python состоит в том, что для обозначения тела функций, циклов, условий и т.д. используются отступы (а не '{' и '}', как в C или C++)
Замечание: отступы должны быть везде строго определенного размера.
a,b = eval(input()) while a!=0 or b!=0: print(a,b) if a == b: print("Было") break a,b = eval(input()) else: print("Не было")
Цикл состоит из 4 частей:
- Инициализация
- Условие
- Тело
- Изменение объектов