在for循环内创建动态字符串以生成多个字符串

时间:2018-07-04 13:33:16

标签: python string python-3.x

我正在研究一个Python(3.6)项目,我需要在一些输入参数的基础上创建一些字符串。

这是我的代码:

def generate_multi_svc_config(data):
    no_of_svc = int(data['configuration']['no_of_svc'])
    deployments = ''''''
    services = ''''''
    for var in list(range(1, no_of_svc + 1)):
        services = services + '''\n
apiVersion: v1
kind: Service
metadata:
  name: {}
  labels:
    app: {}
spec:
  ports:
  - port: {}
    name: {}
  selector:
    app: {}
---
'''.format(data['configuration']['svc' + str(var)]['name'],
           data['configuration']['svc' + str(var)]['name'],
           data['configuration']['svc' + str(var)]['versions']['v1']['port']['port'],
           data['configuration']['svc' + str(var)]['versions']['v1']['port']['name'],
           data['configuration']['svc' + str(var)]['name'])
        print(services)
        deployments = deployments + '''\n
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: {}
  labels:
    #Project ID
    app: {}
spec:
  #Run two instances of our application
  replicas: {}
  template:
    metadata:
      labels:
        app: {}
    spec:
      #Container details
      containers:
        - name: {}
          image: {}
          imagePullPolicy: Always
          #Ports to expose
          ports:
          - containerPort: {}
            name: {}
---
'''.format(data['configuration']['svc' + str(var)]['name'] + '-' + 'v1',
           data['configuration']['svc' + str(var)]['name'],
           data['configuration']['svc' + str(var)]['replicas'],
           data['configuration']['svc' + str(var)]['name'],
           data['configuration']['svc' + str(var)]['name'],
           data['configuration']['svc' + str(var)]['versions']['v1']['image'],
           data['configuration']['svc' + str(var)]['versions']['v1']['port']['port'],
           data['configuration']['svc' + str(var)]['versions']['v1']['port']['name'])
    print(deployments)

因此,当我传递no_of_svc = 2时,它应该创建2个服务字符串和2个部署字符串。

但是它两次创建了服务的第一个条目,而所有其他条目则创建了一次。 我不知道为什么它会两次创建第一个服务字符串?

这是示例输出:

apiVersion: v1
kind: Service
metadata:
  name: ratings
  labels:
    app: ratings
spec:
  ports:
  - port: 8080
    name: ratings-port
  selector:
    app: ratings
---



apiVersion: v1
kind: Service
metadata:
  name: ratings
  labels:
    app: ratings
spec:
  ports:
  - port: 8080
    name: ratings-port
  selector:
    app: ratings
---


apiVersion: v1
kind: Service
metadata:
  name: reviews
  labels:
    app: reviews
spec:
  ports:
  - port: 8081
    name: reviews-port
  selector:
    app: reviews
---



apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: ratings-v1
  labels:
    #Project ID
    app: ratings
spec:
  #Run two instances of our application
  replicas: 3
  template:
    metadata:
      labels:
        app: ratings
    spec:
      #Container details
      containers:
        - name: ratings
          image: gcr.io/ml001-208807/node-app:0.0.1
          imagePullPolicy: Always
          #Ports to expose
          ports:
          - containerPort: 8080
            name: ratings-port
---


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: reviews-v1
  labels:
    #Project ID
    app: reviews
spec:
  #Run two instances of our application
  replicas: 2
  template:
    metadata:
      labels:
        app: reviews
    spec:
      #Container details
      containers:
        - name: reviews
          image: gcr.io/ml001-208807/node-app1:0.0.1
          imagePullPolicy: Always
          #Ports to expose
          ports:
          - containerPort: 8081
            name: reviews-port
---

2 个答案:

答案 0 :(得分:2)

因为在每次迭代中,您都在打印services变量的实际内容,该内容实际上又构成了当前服务以及先前添加的所有内容。

简单地说,您的循环是这样的:

no_of_svc = 2
services = ''
for var in range(1, no_of_svc + 1):
    services += "{} service\n".format(var)
    print(services)

因此,在第二次迭代中,services包含第一服务和第二服务。因此,第一个服务已在两次迭代中打印。

如果您需要将所有值保存为字符串形式的services变量,只需在附加之前仅打印当前值即可:

no_of_svc = 2
services = ''
for var in range(1, no_of_svc + 1):
    service = "service {}\n".format(var)
    print(service)
    services += service

答案 1 :(得分:2)

问题似乎是您在循环的每次迭代中都附加到servicesdeployments上,但是虽然仅在最后打印deployments,但是却打印{{1} } 在循环的每次迭代中,因此将在第一次迭代中添加的条目打印两次。

由于大的多行字符串,这在原始代码中很难看到。我建议将这些字符串提取到模块级别的某些常量,以使循环体更易于阅读。另外,您可以定义一些临时变量以缩短重复的字典查找:

services

此外,如果要在模板字符串的多个位置插入某些值,则可以使用诸如template1 = '''\n apiVersion: v1 ... more lines ... app: {} --- ''' template2 = '''\n apiVersion: extensions/v1beta1 ... more lines ... name: {} --- ''' def generate_multi_svc_config(data): no_of_svc = int(data['configuration']['no_of_svc']) deployments = '' services = '' for var in list(range(1, no_of_svc + 1)): d = data['configuration']['svc' + str(var)] services += template1.format(d['name'], d['name'], d['versions']['v1']['port']['port'], d['versions']['v1']['port']['name'], d['name']) deployments += template2.format(d['name'] + '-' + 'v1', d['name'], d['replicas'], d['name'], d['name'], d['versions']['v1']['image'], d['versions']['v1']['port']['port'], d['versions']['v1']['port']['name']) print(services) # <- move this line here, outside the loop print(deployments) {0}之类的占位符,因此不必传递{1}三遍。

d["name"]