06 类工厂
6.2类工厂函数
是一个用于创建并返回类的函数
-
def create_animal_class(): def init(self, name="lovy"): self.name = name def eat(self): pass def go_to_vet(self): pass return type("Animal", (object, ), { "__doc__": 'A class representing an arbitrary animal.', "__init__": init, "eat": eat, "go_to_vet": go_to_vet, }) Animal1 = create_animal_class() Animal2 = create_animal_class() print(Animal1 == Animal2) # False def create_animal_class(): class Animal(): def __init__(self, name="lovy"): self.name = name def eat(self): pass return Animal Animal1 = create_animal_class() Animal2 = create_animal_class() print(Animal1 == Animal2) # False
6.3 何时编写类工厂
-
运行时属性
def get_credential_class(use_proxy=False, tfa=False): if use_proxy: keys = ["service_name", "email_address"] else: keys = ["username", "password"] if tfa: keys.append("tfa_token") class Credential(object): excepted_keys = set(keys) def __init__(self, **kwargs): if self.excepted_keys != set(kwargs.keys()): raise ValueError("Keys do not match.") for k, v in kwargs.items(): setattr(self, k, v ) return Credential
# 类的属性不固定 import csv def get_credential_class(service): keys = [] with open("creds.csv", "r")as csvfile: for row in csv.reader(csvfile): if row[0].lower() != service.lower(): continue keys.append(row[1]) class Credential(object): expected_keys = keys def __init__(self, **kwargs): if set(self.expected_keys) != set([i for i in kwargs.keys()]): raise ValueError("Keys do not match.") for k, v in kwargs.items(): setattr(self, k, v) return Credential ''' Amazon, username Amazon, password Apple, email_address Apple, password GitHub, username GitHub, password GitHub, auth_token get_credential_class("GitHub") 将会返回一个包含`username、password、auth_token`属性的类 '''
-
避免类属性一致性问题
-
类属性与实例属性
class C: foo = "bar" # 类属性 def __init__(self): self.foo = "bar" # 实例属性
-
类方法的限制
class C: foo = "bar" @classmethod def classfoo(cls): return cls.foo def __init__(self): self.foo = "baz" c1 = C() c2 = C() c2.foo = 123 print(c1.foo) print(c2.classfoo())
-
类工厂尝试
def create_C_subclass(new_foo): class SubC(C): foo = new_foo return SubC S = create_C_subclass("spam") E = create_C_subclass("eggs") print(S.foo) print(E.foo)
-
-
单例模式
# 不需要面对在其他的地方重用类或类工厂可以处理累的重用的情况 def CPrime(new_foo="bar"): if new_foo == "bar": return C() class SubC(C): foo = new_foo return SubC()
-