python 使用全局变量而不在本地范围内将其定义为全局变量

python use of variable from globals without defining it as global in thee local scope

在以下脚本中:

def update_dict(key):
   my_dict[key] = ...


mydict = dict()
k = ...
update_dict(k)

my_dict 尚未在 class 中声明,但已在 update_dict 中使用。
1-口译员允许这种情况发生。 python 不应该对此报错吗?
2- 使用全局变量而不在使用它的局部范围内将其声明为全局变量会带来什么问题? python是否根据变量名使用指向全局变量的指针?


这个片段是我做的一个总结,如果你认为(也许是正确的?)我在我的总结中犯了一个错误,那么完整的代码就在这一段之后。相当于 mydict 这里是 sites.

import sys
import csv
import argparse
import gzip

class SiteStats:
    def __init__(self, g_size, g_seq):
        self.num_reads = 0
        self.called_sites = 0
        self.called_sites_methylated = 0
        self.group_size = g_size
        self.sequence = g_seq

def update_call_stats(key, num_called_cpg_sites, is_methylated, sequence):
    if key not in sites:
        sites[key] = SiteStats(num_called_cpg_sites, sequence)

    sites[key].num_reads += 1
    sites[key].called_sites += num_called_cpg_sites
    if is_methylated > 0:
        sites[key].called_sites_methylated += num_called_cpg_sites

parser = argparse.ArgumentParser( description='Calculate methylation frequency at genomic CpG sites')
parser.add_argument('-c', '--call-threshold', type=float, required=False, default=2.0)
parser.add_argument('-s', '--split-groups', action='store_true')
args, input_files = parser.parse_known_args()
assert(args.call_threshold is not None)

sites = dict()
# iterate over input files and collect per-site stats
for f in input_files:
    if f[-3:] == ".gz":
        in_fh = gzip.open(f, 'rt')
    else:
        in_fh = open(f)
    csv_reader = csv.DictReader(in_fh, delimiter='\t')
    for record in csv_reader:

        num_sites = int(record['num_motifs'])
        llr = float(record['log_lik_ratio'])

        # Skip ambiguous call
        if abs(llr) < args.call_threshold * num_sites:
            continue
        sequence = record['sequence']

        is_methylated = llr > 0

        # if this is a multi-cpg group and split_groups is set, break up these sites
        if args.split_groups and num_sites > 1:
            c = str(record['chromosome'])
            s = int(record['start'])
            e = int(record['end'])

            # find the position of the first CG dinucleotide
            sequence = record['sequence']
            cg_pos = sequence.find("CG")
            first_cg_pos = cg_pos
            while cg_pos != -1:
                key = (c, s + cg_pos - first_cg_pos, s + cg_pos - first_cg_pos)
                update_call_stats(key, 1, is_methylated, "split-group")
                cg_pos = sequence.find("CG", cg_pos + 1)
        else:
            key = (str(record['chromosome']), int(record['start']), int(record['end']))
            update_call_stats(key, num_sites, is_methylated, sequence)

# header
print("\t".join(["chromosome", "start", "end", "num_motifs_in_group", "called_sites", "called_sites_methylated", "methylated_frequency", "group_sequence"])
)

sorted_keys = sorted(list(sites.keys()), key = lambda x: x)

for key in sorted_keys:
    if sites[key].called_sites > 0:
        (c, s, e) = key
        f = float(sites[key].called_sites_methylated) / sites[key].called_sites
        print("%s\t%s\t%s\t%d\t%d\t%d\t%.3f\t%s" % (c, s, e, sites[key].group_size, sites[key].called_sites, sites[key].called_sites_methylated, f, sites[k
ey].sequence))

谢谢!

global varname 仅在分配给全局变量时才需要,否则它会被假定为创建的新本地变量。对于所有其他情况,Python 已经知道它应该是正在使用的全局并且没有歧义。

在您的示例代码中,您在全局字典上设置 key/value 对,而不是分配给全局变量:

def update_dict(key):
    my_dict[key] = ...

以下是您需要 global 才能修改全局 b 的情况:

b = 0
def a():
    global b
    b = 2
print(b)
a()
print(b)

输出:

0
2