整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          python學習筆記(基本語法+腳本)

          本語法

          1. 簡單控制語句

          字符串推薦用'' 單引號引用

          list: List[int] = [1, 2, 3]
          for elem in list:
              if elem > 1:
                  print(f'data {elem} > 1')  # 這里是format語句,屬于語法糖
              else:
                  print(f'data {elem} < 1')
          
          '''
          data 1 < 1
          data 2 > 1
          data 3 > 1
          '''

          2. 異常

          x = -1
          try:
              if x < 0:
                  raise Exception("Sorry, no numbers below zero")
          except Exception as err:
              print("find err: %s" % err)
          '''
          find err: Sorry, no numbers below zero
          ''' 

          3. 推導式(比較晦澀難懂)

          • 參考: https://www.cnblogs.com/desireyang/p/12160332.html

          推導式好處: 效率更高,底層是c執行

          1. 列表推導式

          一共兩種形式:(參考: https://zhuanlan.zhihu.com/p/139621170) , 它主要是輸出是列表(list)

          • [xforxindataifcondition] 這里的含義是data只有滿足if條件中的情況才保留 (if)
          • [exp1ifconditionelseexp2forxindata] , 這里的含義是data滿足if條件時執行exp1 否則 exp2 (if - else)
          import re
          
          """
          獲取所有的數字
          """
          list = ["1", "2", "3", "4", "5", "a", "b", "c"]
          print([elem for elem in list if re.match("\\d", elem)])
          '''
          ['1', '2', '3', '4', '5']
          '''
          
          """
          獲取所有的字母
          """
          print([elem for elem in list if re.match("[a-z]", elem)])
          '''
          ['a', 'b', 'c']
          '''
          
          """
          如果元素是數字則存儲,否則則upper
          """
          print([elem if re.match("\\d", elem) else elem.upper() for elem in list])
          '''
          ['1', '2', '3', '4', '5', 'A', 'B', 'C']
          '''

          最佳實踐: 參考(https://github.com/httpie/httpie/blob/master/httpie/core.py#L235)

          def decode_raw_args(
                  args: List[Union[str, bytes]],
                  stdin_encoding: str
          ) -> List[str]:
              """
              Convert all bytes args to str
              by decoding them using stdin encoding.
          
              """
              return [
                  arg.decode(stdin_encoding)
                  if type(arg) is bytes else arg
                  for arg in args
              ]
          
          
          def decode_raw_args_parse(
                  args: List[Union[str, bytes]],
                  stdin_encoding: str
          ) -> List[str]:
              """
              Convert all bytes args to str
              by decoding them using stdin encoding.
              不使用推導式
              """
              result: List[str] = []
              for arg in args:
                  if type(arg) is bytes:
                      result.append(arg.decode(stdin_encoding))
                  else:
                      result.append(arg)
              return result
          
          
          # arg.decode(stdin_encoding) if type(arg) is bytes else arg for arg in args
          print(decode_raw_args(args=[b'111', b'222'], stdin_encoding="utf-8"))
          print(decode_raw_args(args=["111", "222"], stdin_encoding=""))
          '''
          ['111', '222']
          ['111', '222']
          '''
          
          print(decode_raw_args_parse(args=[b'111', b'222'], stdin_encoding="utf-8"))
          print(decode_raw_args_parse(args=["111", "222"], stdin_encoding=""))
          '''
          ['111', '222']
          ['111', '222']
          '''

          2. 字典推導式

          {key_expr:value_exprforvalueincollectionifcondition} ,輸出是dict

          """
          { key_expr: value_expr for value in collection if condition }
          
          反轉key value,且獲取 value 為在set {'a', 'b', 'c'}中的元素
          """
          dict_old = {'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D'}
          print({dict_old[value]: value for value in dict_old if value in {'a', 'b', 'c'}})
          '''
          {'A': 'a', 'B': 'b', 'C': 'c'}
          '''
          
          print({key: value for value, key in dict_old.items() if value in {'a', 'b', 'c'}})
          '''
          {'A': 'a', 'B': 'b', 'C': 'c'}
          '''

          3. 集合推導式

          表達式:

          • {exprforvalueincollectionifcondition}
          • {exp1ifconditionelseexp2forxindata}輸出是set

          其實就是上面列表推導式[] 換成{} ,輸出由list 變成了set

          4. for 循環 迭代器

          import os
          from collections.abc import Iterable
          
          with open("text.log", "wt") as file:
              file.truncate()
              file.writelines("line 1" + os.linesep)
              file.writelines("line 2" + os.linesep)
              file.writelines("line 3" + os.linesep)
              pass
          
          with open("text.log", "rt") as file:
              for line in file:
                  print("type: {type}, isinstance: {isinstance}, line: {line}".format(type=type(file),
                                                                                      isinstance=isinstance(file, Iterable),
                                                                                      line=line))
              pass
          
          '''
          type: <class '_io.TextIOWrapper'>, isinstance: True, line: line 1
          
          type: <class '_io.TextIOWrapper'>, isinstance: True, line: line 2
          
          type: <class '_io.TextIOWrapper'>, isinstance: True, line: line 3
          '''

          這里面_io.TextIOWrapper 實現了 __next__() 方法

          比如我們自己實現一個可迭代的對象

          下面可以看到我使用了類型申明List[str] 其實這個python運行時并不會檢測,需要工具進行檢測!

          變量默認都是Any 類型 ,具體可以看 https://docs.python.org/zh-cn/3/library/typing.html

          from typing import List
          
          class Items(object):
              def __init__(self, list: List[str]):
                  self.list = list
                  self.index = 0
          
              def __next__(self, *args, **kwargs):
                  """
                  next,沒有拋出StopIteration
                  """
                  if self.index >= len(self.list):
                      raise StopIteration
                  result = self.list[self.index]
                  self.index = self.index + 1
                  return result
          
              def __iter__(self, *args, **kwargs):
                  """
                  返回一個迭代器
                  """
                  return self
          
          
          data = Items(["1", "2", "3"])
          
          for x in data:
              print(x)
          '''
          1
          2
          3
          '''

          5. 包管理

          from ..a import foo  # 上級目錄
          from .a import foo_a  # 當前目錄
          
          import sys  # 引用源碼或者lib
          from copy import deepcopy  # 引用源碼或者lib
          
          from pygments.formatters.terminal import TerminalFormatter  # 引用 lib.lib.file
          
          import demo.utils.a
          
          
          def c_foo():
              demo.utils.a.foo_a()
              TerminalFormatter()
              deepcopy()
              print(sys.api_version)
          
          
          def b_foo():
              foo()

          基本數據類型

          1. 定義方式

          • mylist:list[str]=["apple","banana","cherry"]
          • mylist=["apple","banana","cherry"]

          Text Type:

          str

          Numeric Types:

          int,float,complex

          Sequence Types:

          list,tuple,range

          Mapping Type:

          dict

          Set Types:

          set,frozenset

          Boolean Type:

          bool

          Binary Types:

          bytes,bytearray,memoryview

          2. 數字基本類型

          x = 1  # int
          y = 1.1  # float
          z = 1j  # 復數(complex)
          a = complex(1, 2)  # 復數(complex)
          print(type(x))
          print(type(y))
          print(type(z))
          print(z.imag, z.real)
          print(type(a))
          print(a.imag, a.real)
          '''
          <class 'int'>
          <class 'float'>
          <class 'complex'>
          1.0 0.0
          <class 'complex'>
          2.0 1.0
          '''

          3. 字符串

          str = "hello"
          print(str)
          print(str[0:])
          print(str[:5])
          print(str[:-1])
          print(str[0:5])
          print(str[0:5:1])
          print(str[0:5:2])
          '''
          hello
          hello
          hello
          hell
          hello
          hello
          hlo
          '''
          
          # format
          print("My name is {} and age is {}".format("tom", 18))
          '''
          My name is tom and age is 18
          '''
          
          quantity = 3
          itemno = 567
          price = 49.95
          myorder = "I want to pay {2} dollars for {0} pieces of item {1}."
          print(myorder.format(quantity, itemno, price))
          '''
          I want to pay 49.95 dollars for 3 pieces of item 567.
          '''
          
          # func
          str = "hello world! "
          print(str.upper())
          print(str.lower())
          print(str.strip())
          print(str + " ...")
          '''
          HELLO WORLD! 
          hello world! 
          hello world!
          hello world!  ...
          '''
          
          # format
          myorder = "I have a {carname}, it is a {model}."
          print(myorder.format(carname="Ford", model="Mustang"))
          '''
          I have a Ford, it is a Mustang.
          '''

          4. lambda

          其實就是一個func

          def add(num):
              return lambda x: x + num
          
          
          print(add(10)(10))
          '''
          20
          '''

          lanbda 例子2

          import json
          
          class Obj:
              def __init__(self):
                  self.name = "tom"
                  self.age = 1
          
          
          print(json.dumps(Obj(), default=lambda obj: obj.__dict__))
          '''
          {"name": "tom", "age": 1}
          '''

          集合

          list,tuple,range,dict,set,frozenset

          • list , 例如:mylist=["apple","banana","cherry"]
          • tuple 是特殊的數組,就是不能改變, 例如mytuple=("apple","banana","cherry")
          • range 可以理解是個迭代器, 例如:
          • dict 就是個map, 例如:thisdict={"brand":"Ford","model":"Mustang","year":1964}
          • set 就是個去重復的list , 例如:myset={"apple","banana","cherry"}

          1. list

          mylist = ["apple", "banana", "cherry"]
          
          # 切片
          print(mylist[0])
          print(mylist[2])
          print(mylist[-1])
          print(mylist[0:3:2])
          '''
          apple
          cherry
          cherry
          ['apple', 'cherry']
          '''
          
          # 基本操作
          mylist.append("orange")
          print(mylist)
          '''
          ['apple', 'banana', 'cherry', 'orange']
          '''
          
          mylist.insert(0, "mango")
          print(mylist)
          '''
          ['mango', 'apple', 'banana', 'cherry', 'orange']
          '''
          
          # 循環
          for x in mylist:
              print(x)
          
          '''
          apple
          banana
          cherry
          orange
          '''
          
          for index in range(len(mylist)):
              print("index: %d" % index)
          '''
          index: 0
          index: 1
          index: 2
          index: 3
          index: 4
          '''
          
          if "apple" in mylist:
              print("success!")
          
          '''
          success!
          '''
          
          # [執行表達式(也就是for循環中的,如果有if則是if中執行的), for item in list 條件表達式]
          new_list = [elem.upper() for elem in mylist if "a" in elem]  # contains 'a' char elem str
          print(new_list)
          '''
          ['MANGO', 'APPLE', 'BANANA', 'ORANGE']
          '''
          
          newList = []
          for elem in mylist:
              if 'a' in elem:
                  newList.append(elem.upper())
          print(newList)
          '''
          ['MANGO', 'APPLE', 'BANANA', 'ORANGE']
          '''

          2. map

          thisdict = {"brand": "Ford", "model": "Mustang", "year": 1964}
          
          for key, value in thisdict.items():
              print("key: {}, value: {}".format(key, value))
          
          '''
          key: brand, value: Ford
          key: model, value: Mustang
          key: year, value: 1964
          '''
          
          for key in thisdict:
              print("key: {}, value: {}".format(key, thisdict[key]))
          '''
          key: brand, value: Ford
          key: model, value: Mustang
          key: year, value: 1964
          '''

          3. range

          # range 會生成一個迭代器,(start,end,sep) , 左閉右開
          for x in range(6):  # [0,1,2,3,4,5]
              print("x is %d" % x)
          '''
          x is 0
          x is 1
          x is 2
          x is 3
          x is 4
          x is 5
          '''
          
          for x in range(2, 6):
              print("x is %d" % x)
          
          '''
          x is 2
          x is 3
          x is 4
          x is 5
          '''
          
          for x in range(1, 6, 2):
              print("x is %d" % x)
          '''
          x is 1
          x is 3
          x is 5
          '''

          方法

          1. 定義一個空方法

          def func_1():
              pass  # 空方法必須申明pass
          
          
          func_1()

          2. 參數

          # name 為必須添的參數,不然為空會報錯
          # age 為默認參數
          # agrs 為可變參數
          # kwargs 為 k v 參數
          def func_1(name, age=1, *args, **kwargs):
              print("name: %s" % name)
              print("age: %d" % age)
              print("len(args): {}, type: {}".format(len(args), type(args)))
              for value in args:
                  print("args value: {}".format(value))
          
              print("len(kwargs): {}, type: {}".format(len(kwargs), type(kwargs)))
              for key, value in kwargs.items():
                  print("kwargs key: {}, value: {}".format(key, value))
          
          
          func_1(name="tom", age=10, args="1", kwargs="2")
          '''
          name: tom
          age: 10
          len(args): 0
          len(kwargs): 0, type: <class 'tuple'>
          len(kwargs): 2, type: <class 'dict'>
          kwargs key: args, value: 1
          kwargs key: kwargs, value: 2
          '''
          
          # 這里注意由于dict所以不能申明kv
          func_1("tom", 10, "1", "2", args="1", kwargs="2")
          '''
          name: tom
          age: 10
          len(args): 2, type: <class 'tuple'>
          args value: 1
          args value: 2
          len(kwargs): 2, type: <class 'dict'>
          kwargs key: args, value: 1
          kwargs key: kwargs, value: 2
          '''

          3. 類型

          申明輸入輸出類型

          from typing import List, Union
          def decode_raw_args(
              args: List[Union[str, bytes]],
              stdin_encoding: str
          ) -> List[str]:
              """
              Convert all bytes args to str
              by decoding them using stdin encoding.
          
              """
              return [
                  arg.decode(stdin_encoding)
                  if type(arg) is bytes else arg
                  for arg in args
              ]

          1. 定義類和方法

          # 如果沒有父類繼承,這里選擇 object,比較規范
          class Person(object):
              # gender none, male or female
              gender = "none"
          
              # 構造器
              def __init__(self, name, age):
                  self.name = name
                  self.age = age
          
              def my_name(self):
                  return self.name
          
          
          p = Person(name="tome", age=1)
          print(p.my_name())

          2. 類型的繼承

          import json
          
          
          class Person(object):
              # gender none, male or female
              gender = "none"
          
              # 構造器
              def __init__(self, name, age):
                  self.name = name
                  self.age = age
          
              def my_name(self):
                  return self.name
          
          
          p = Person(name="tome", age=1)
          print(p.my_name())
          
          
          class Mail(Person):
              def __init__(self, name, age):
                  super(Mail, self).__init__(name, age)
                  self.gender = "mail"
          
              def my_name(self):
                  return self.name + "_mail"
          
          
          p = Mail(name="tome", age=1)
          print(json.dumps(p, default=lambda obj: obj.__dict__))
          print(p.my_name())

          3. 類__new__函數

          主要是__init__執行前會調用

          #!/usr/bin/python
          
          import json
          
          
          class Person(object):
              def __new__(cls, *args, **kwargs):
                  instance = object.__new__(cls)
                  instance.job = "it"
                  return instance
          
              # construct
              def __init__(self, name, age):
                  self.name = name
                  self.age = age
          
              def to_json(self):
                  return json.dumps(self, default=lambda obj: obj.__dict__)
          
          
          p = Person(name="tome", age=1)
          print(p.to_json()) # {"age": 1, "job": "it", "name": "tome"}

          其他用法技巧

          1. 斷言

          if type(1) is int:
              print("args is int")
              ...  # 等效 pass
          '''
          args is int
          '''

          2. 測試<<<

          可以參考文件: https://segmentfault.com/q/1010000010389542 , 屬于doctest

          def humanize_bytes(n, precision=2):
              # Author: Doug Latornell
              # Licence: MIT
              # URL: https://code.activestate.com/recipes/577081/
              """Return a humanized string representation of a number of bytes.
          
              >>> humanize_bytes(1)
              '1 B'
              >>> humanize_bytes(1024, precision=1)
              '1.0 kB'
              >>> humanize_bytes(1024 * 123, precision=1)
              '123.0 kB'
              >>> humanize_bytes(1024 * 12342, precision=1)
              '12.1 MB'
              >>> humanize_bytes(1024 * 12342, precision=2)
              '12.05 MB'
              >>> humanize_bytes(1024 * 1234, precision=2)
              '1.21 MB'
              >>> humanize_bytes(1024 * 1234 * 1111, precision=2)
              '1.31 GB'
              >>> humanize_bytes(1024 * 1234 * 1111, precision=1)
              '1.3 GB'
          
              """
              abbrevs = [
                  (1 << 50, 'PB'),
                  (1 << 40, 'TB'),
                  (1 << 30, 'GB'),
                  (1 << 20, 'MB'),
                  (1 << 10, 'kB'),
                  (1, 'B')
              ]
          
              if n == 1:
                  return '1 B'
          
              for factor, suffix in abbrevs:
                  if n >= factor:
                      break
          
              # noinspection PyUnboundLocalVariable
              return f'{n / factor:.{precision}f} {suffix}'

          3. yield

          • 參考: https://zhuanlan.zhihu.com/p/268605982

          其實類似于程序的斷電,比如程序運行到那里其實是返回一個生成器,然后當你下一步是才會執行,比較節省內存

          from typing import List
          
          
          def new(size: int = 1024 * 1024):
              yield new_data(size)
          
          
          def new_data(size: int) -> List[int]:
              return [0] * size
          
          
          data = new()
          print(type(data))
          print(len(next(data)))  # 只能執行一次 next不然報錯
          '''
          <class 'generator'>
          1048576
          '''

          腳本

          base64輸出

          echo "aGVsbG8gcHl0aG9uCg==" | python -c "import sys,base64; print(sys.stdin.read())"
          
          ->
          
          echo "aGVsbG8gcHl0aG9uCg==" | python -c "import sys,base64; print(base64.b64decode(sys.stdin.read()))"
          -> stdout:
          b'hello python\n'

          文件操作

          • r ,w,x ,a四種類型(a: append, w=truncate+create, x=truncate+create if not exit)
          • b,t 文件類型

          第一列可以和第二列文件類型組合,第一列不允許并存

          import os
          
          
          with open("file.log", "w") as file:
              for x in range(0, 100):
                  file.write("hello world"+os.linesep)
          
          
          with open("file.log","r") as file:
              for line in file.readlines():
                  print(line)

          json

          import json
          
          print(json.dumps({"k1": "v1", "k2": [1, 2, 3]}))
          print(json.loads('{"k1": "v1", "k2": [1, 2, 3]}'))

          如果是class,需要繼承JSONEncoder和JSONDecoder實現子類 ,或者

          import json, datetime
          
          class Demo(object):
              def __init__(self, name: str, age: int, birthday: datetime.date):
                  self.name = name
                  self.agw = age
                  self.birthday = birthday
          
              def to_json(self, _):
                  return {"name": self.name, "age": self.agw, "birthday": self.birthday.strftime("%Y-%m-%d")}
          
          
          data = Demo("tom", 18, datetime.date(2001, 1, 1))
          print(json.dumps(data, default=data.to_json))

          typing (申明類型)

          官方文檔: https://docs.python.org/zh-cn/3/library/typing.html

          可以參考這篇文章: https://sikasjc.github.io/2018/07/14/type-hint-in-python/

          對于喜歡靜態類型的語言,我覺得是非常nice的

          應上篇,續講前文。今天咱來聊一下Dockerfile的使用 。


          雖然可以通過docker commit命令來手動創建鏡像,但是通過Dockerfile文件,可以幫助我們自動創建鏡像,并且能夠自定義創建過程。本質上,Dockerfile就是一系列命令和參數構成的腳本,這些命令應用于基礎鏡像并最終創建一個新的鏡像,簡化了從頭到尾的構建流程并極大地簡化了部署工作。

          使用Dockerfile的優點:

          • 像編程一樣構建鏡像,支持分層構建及緩存。
          • 可以快速而精確的重新創建鏡像以便于維護和升級。
          • 便于持續集成。
          • 可在任何地方快速構建鏡像。


          一、Dockerfile構建鏡像步驟


          1、創建Dockerfile文件,名字就是Dockerfile

          2、docker build Dockerfile所在路徑 -t 鏡像名稱[:tag]


          二、Dockerfile指令


          1、FORM

          FORM指令是最重要的一個且必須為Dockerfile文件開篇的第一個非注釋行,用于為映像文件構建過程指定基準鏡像,后續的指令運行于此基準鏡像所提供的運行環境。

          基準鏡像可以是任務可用鏡像文件,默認情況下,docker build會在docker主機上查找指定的鏡像文件,如果不存在,則會從Docker Hub Registry上拉取所需的鏡像文件。

          也就是說,任何新建鏡像必須基于已有的鏡像進行構建。


          格式:FROM 鏡像名稱[:tag]

          例如:FROM ngxin


          2、MAINTAINER

          用于讓Dockerfile制作者提供本人的詳細信息,此指令位置不限,但推薦放置FROM之后。

          格式:MAINTAINER 作者信息

          例如:MAINTAINER "lsy"


          3、LABLE

          為鏡像指定標簽,會繼承基礎鏡像的LABLE,如果key相同,則覆蓋??商娲鶰AINTANIER使用。


          格式:LABLE key1=value1 key2=value2

          例如:LABLE author=lsy

          4、RUN

          指定要運行并捕獲到新容器鏡像中的命令,包括安裝文件、創建文件等,在容器創建過程中執行。


          格式 :RUN 指令1 [&& 指令2]


          注意:由于Dockerfile中每一個指令都會創建一層,所有層一起構成新的鏡像。如果指令過多的話,會變得很臃腫,增加構建時間,所以可以將指令合并執行

          例如:RUN mkdir -p /usr/lsy && echo 'this is lsy file' > /usr/lsy/lsy.html


          例如下面這個Dockerfile文件:

          基于nginx創建一個鏡像,并創建/usr/lsy目錄并創建lsy.html文件

          FROM nginx
          MAINTAINER "lsy"
          RUN mkdir -p /usr/lsy &&  echo 'this is lsy file' > /usr/lsy/lsy.html

          使用命令進行構建

          docker build ./ -t my_nginx_1:v1.1

          可以看到,docker會一層層的進行構建。

          啟動鏡像:

          docker run --rm --name my_nginx_1 -it my_nginx_1:v1.1 /bin/bash



          可以看到,容器中確實是執行了RUN指令。


          5、COPY

          將宿主機的文件或者目錄拷貝到容器的文件系統中,需相對于Dockerfile的路徑。


          格式:COPY <src> <dest>

          文件復制準則:

          1. <src>必須是build上下文的相對路徑。
          2. <src>是目錄的話,則內部文件或子目錄會遞歸復制,但是目錄自身不會被復制
          3. 如果指定多個src,則dest必須是一個目錄,且必須以/結尾
          4. 目標路徑如果不存在,則會自動創建

          例如:把Dockerfile同目錄的test.html文件拷貝到容器中的/usr/lsy目錄中

          FROM nginx
          MAINTAINER "lsy"
          RUN mkdir -p /usr/lsy &&  echo 'this is lsy file' > /usr/lsy/lsy.html
          COPY ./test.html /usr/lsy


          使用docker build對Dockerfile進行構建:

          啟動容器查看文件是否已拷貝:


          6、ADD

          功能與COPY類似,還可以使用url規范從遠程位置復制到容器中


          格式 :ADD <source> <dest>

          例如:ADD ./test.html /usr/lsy

          ADD https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe /temp/python-3.5.1.exe


          7、WORKDIR

          用于為其他Dockerfile指令(如 RUN、CMD)設置一個工作目錄,并且還設置用于運行容器映像實例的工作目錄。WORKDIR之后的指令都會基于設定的工作目錄中運行。


          格式:WORKDIR 路徑

          例如:將/usr/lsy設置為工作目錄,然后在目錄中創建一個a.html文件

          FROM nginx
          MAINTAINER "lsy"
          RUN mkdir -p /usr/lsy
          WORKDIR /usr/lsy
          RUN touch a.html

          使用docker build創建鏡像

          運行容器查看:

          可以看到,進來容器就是在工作目錄中,并且目錄中有了需要創建的文件。


          8、CMD

          類似于RUN指令,CMD指令也可用于運行任何命令或應用程序,不過,兩者的運行時間不同。

          RUN指令運行于 鏡像創建過程中,而CMD指令運行于基于Dockerfile構建出的鏡像啟動一個容器時。

          CMD指令的目的在于為啟動的容器指定默認要運行的程序,且其運行結束后,容器也將終止,不過CMD指令可以被docker run的命令行參數所覆蓋。

          Dockerfile中可以指定多個CMD命令,但只有最后一個才會生效。


          格式:CMD <command>

          CMD ['<executable>','<param1>','<param2>']

          CMD ['<param1>','<param2>']

          前兩種語法跟RUN一樣

          第三種是用于為ENTERPOINT指令提供默認參數。


          例如:CMD c:\Apache24\bin\httpd.exe -w

          CMD ['/bin/bash','-c','c:\Apache24\bin\httpd.exe','-w']


          9、ENTERPOINT

          配置容器啟動后執行的命令,并且不可被 docker run 提供的參數覆蓋。每個 Dockerfile 中只能有一個ENTRYPOINT,當指定多個時,只有最后一個起效。如果有CMD,則CMD的命令被當作參數傳遞給ENTERPOINT。

          不過,docker run命令的--entrypoint選項的參數可以對Dockerfile中的ENTRYPOINT進行覆蓋。

          Dockerfile中可存在多個 ENTRYPOINT指令,但只有最后一個 才會執行。


          格式:ENTRYPOINT <command>

          ENTRYPOINT ['<executable>','<param1>','<param2>']


          10、ENV

          用于為鏡像定義所需的環境變量,并可被Dockerfile文件中位于其后的其他指令所調用。

          調用格式為${variable_name}或$variable_name


          格式:ENV key1=value1 key2=value2

          ENV key value


          11、ARG

          構建參數,作用于ENV相同,不同的是ARG的參數只在構建鏡像的時候起作用,也就是docker build的時候。


          格式:ARG k=v


          12、EXPOSE

          用來指定端口,是容器內的應用可以通過端口與外界交互

          作用跟docker run 命令中的 -p 一樣


          格式:EXPOSE 端口

          例如:EXPOSE 80


          13、VOLUME

          用于在鏡像中創建一個掛載點目錄,以掛載Docker Host上的卷或其他容器上的卷

          如果掛載點目錄路徑下此前的文件存在,docker run命令會在卷掛載完之后將此前的所有文件 復制到新掛載的卷中。


          格式:VOLUME <路徑>

          VOLUME ["<路徑1>", "<路徑2>"...]


          14、USER

          用于執行后續命令的用戶和用戶組


          格式 :USER 用戶名[:用戶組]

          例如:USER root:root


          15、HEALTHCHECK

          用于指定某個程序或者指令來監控 docker 容器服務的運行狀態。


          格式:HEALTHCHECK [OPTIONS] CMD command

          HEALTHCHECK NONE

          第一個的功能是在容器內部運行一個命令來檢查容器的健康狀況

          第二個的功能是在基礎鏡像中取消健康檢查命令


          [OPTIONS]的選項支持以下三中選項:

          --interval=DURATION 兩次檢查默認的時間間隔為30秒

          --timeout=DURATION 健康檢查命令運行超時時長,默認30秒

          --retries=N 當連續失敗指定次數后,則容器被認為是不健康的,狀態為unhealthy,默認次數是3

          --start-period=DURATION 容器啟動后多長時間開始執行,默認是0s


          注意:

          HEALTHCHECK命令只能出現一次,如果出現了多次,只有最后一個生效。


          CMD后邊的命令的返回值決定了本次健康檢查是否成功,具體的返回值如下:

          0: success - 表示容器是健康的

          1: unhealthy - 表示容器已經不能工作了

          2: reserved - 保留值


          例如:定時 30s PING一下百度,如果PING失敗,則返回1

          FROM nginx
          MAINTAINER "lsy"
          HEALTHCHECK --timeout=3s \
                  CMD curl -f http://localhost/ || exit 1

          使用docker build構建鏡像

          運行容器,查看日志輸出:


          16、ONBUILD

          用于延遲構建命令的執行。簡單的說,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次構建鏡像的過程中不會執行(假設鏡像為 test-build)。當有新的 Dockerfile 使用了之前構建的鏡像 FROM test-build ,這是執行新鏡像的 Dockerfile 構建時候,會執行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。


          格式 :ONBUILD <其它指令>

          VOLUME

          17、STOPSIGNAL

          當容器退出時給系統發送什么樣的指令


          格式:STOPSIGNAL 指令


          ===============================

          我是Liusy,一個喜歡健身的程序員。

          獲取更多干貨以及最新消息,請關注公眾號:上古偽神

          如果對您有幫助,點個關注就是對我最大的支持!??!

          使用Python進行Web開發,你需要掌握一系列關鍵的知識和技能。以下是一份涵蓋基本和進階方面的學習清單:

          基礎知識:

          1、Python基礎:

          對Python語言的基本語法、數據類型、控制流程等有清晰的理解。

          2、HTML和CSS:

          掌握HTML(超文本標記語言)和CSS(層疊樣式表),用于創建和美化網頁。

          3、JavaScript:

          了解JavaScript,它是用于在網頁上添加交互性和動態特效的腳本語言。

          4、Web協議和網絡基礎:

          了解HTTP/HTTPS協議,以及網絡通信的基本原理。

          5、前端框架:

          學習至少一個前端框架,如React、Vue.js或Angular,用于構建動態、響應式的用戶界面。

          后端知識:

          1、Web框架:

          掌握Python的Web框架,例如Django、Flask或FastAPI。這些框架提供了一系列工具和模塊,加速Web應用的開發。

          2、模板引擎:

          了解并使用模板引擎(如Jinja2),用于在服務器端生成動態的HTML頁面。

          3、數據庫:

          學習使用數據庫,理解SQL語言,以及如何在Web應用中進行數據庫操作。常見的數據庫包括MySQL、PostgreSQL、SQLite等。

          4、ORM(對象關系映射):

          了解并使用ORM框架(例如Django的ORM或SQLAlchemy),簡化與數據庫的交互。

          5、RESTful API設計:

          學習設計和實現RESTful API,使你的應用可以通過API與其他系統進行通信。

          安全性和性能優化:

          1、安全性:

          了解Web應用的常見安全問題,學習如何防范跨站腳本攻擊(XSS)、跨站請求偽造(CSRF)等攻擊。

          2、身份驗證和授權:

          學習如何實現用戶身份驗證和授權機制,確保應用的安全性。

          3、性能優化:

          了解如何優化數據庫查詢、前端資源加載,以及使用緩存和CDN等技術提升應用性能。

          版本控制和協作:

          1、Git:

          學習使用Git進行版本控制,以便有效地協作和管理代碼。

          2、團隊協作:

          了解團隊協作工具,如GitHub、GitLab等,以便與其他開發者協同工作。

          部署和運維:

          1、服務器和部署:

          了解Web服務器的基本原理,學習如何在服務器上部署Python應用。熟悉常見的部署工具,如Docker、Nginx等。

          2、日志和監控:

          學習記錄和監控應用的技術,以便及時發現和解決問題。

          3、自動化:

          掌握自動化部署和測試的工具,如Jenkins、Travis CI等。

          測試:

          1、單元測試和集成測試:

          學習編寫和運行單元測試和集成測試,確保代碼的質量和穩定性。

          2、前端測試:

          了解前端測試框架,如Jest、Testing Library等,用于測試前端組件和交互。

          以上清單涵蓋了Python Web開發的基本要素,你可以根據具體項目需求和興趣深入學習相關的技術。實際項目和不斷的實踐也是鞏固這些知識的重要途徑。


          主站蜘蛛池模板: 国精无码欧精品亚洲一区| 国产成人一区二区三区高清 | 欧美激情一区二区三区成人| 国产精品视频一区国模私拍| 精品无码综合一区二区三区| 精品国产不卡一区二区三区| 国产乱码精品一区二区三区中| 国产伦精品一区二区三区精品 | 国产精品亚洲高清一区二区| 国产亚洲一区二区三区在线| 国产一区二区三区播放| 国产欧美一区二区精品仙草咪| 亚洲图片一区二区| 国产伦精品一区二区三区| а天堂中文最新一区二区三区| 八戒久久精品一区二区三区| 国产成人欧美一区二区三区| 2021国产精品视频一区| 国产乱码一区二区三区| 无码人妻啪啪一区二区| 国产Av一区二区精品久久| 无码一区二区三区在线| 成人精品视频一区二区三区尤物| 日本高清一区二区三区| 亚洲AV无码一区二区三区鸳鸯影院| 99久久无码一区人妻a黑| 色综合视频一区二区三区44| 亚洲AV成人一区二区三区在线看| 国产午夜福利精品一区二区三区 | 亚洲一区二区三区AV无码| 精品免费久久久久国产一区 | 少妇精品久久久一区二区三区| 国产精品日本一区二区在线播放| 免费看一区二区三区四区| 国产另类TS人妖一区二区| 国99精品无码一区二区三区| 无码人妻品一区二区三区精99| 精品女同一区二区三区免费站| 精品无码国产一区二区三区51安 | 久久久国产一区二区三区| 久久国产精品一区免费下载|