简体   繁体   English

用于在Python中为变量分配类的用途

[英]Uses of assigning a class to a variable in Python

Is there any good reason why one would assign a class to a variable as shown in the code below ? 有没有什么好的理由可以将一个类分配给变量,如下面的代码所示? What are some useful/interesting things one can do thanks to that mechanic ? 由于这个机制,可以做些什么有用/有趣的事情?

class foo:

    # Some initialization stuff
    def __init__(self):
        self.x = 0

    # Some methods and other stuff

myVar = foo

The case I've seen most often in production code is dependency injection or "compile-time" configuration. 我在生产代码中经常看到的情况是依赖注入或“编译时”配置。

For example, I may have some classes that implement some strategy or command, but I don't have the details for the constructor yet. 例如,我可能有一些实现某些策略或命令的类,但我还没有构造函数的详细信息。

class StrategyOne:...
class StrategyTwo:...

def my_func(vars, Strategy):
    x = some_calculation(vars)
    st = Strategy(x)

An example of using this as configuration can be seen in the django-rest-framework docs django-rest-framework文档中可以看到使用它作为配置的示例

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ('id', 'account_name', 'users', 'created')

I think most uses cases fall into the principle of "I don't want to couple to this particular class". 我认为大多数用例都属于“我不想结合这个特殊阶级”的原则。 Another level of indirection and all. 另一层次的间接和所有。

Take the type checking example for instance. 类型检查示例为例。 The loop over the collection of types [x for x in lst if isinstance(x, types)] does not depend on any particular types and is thus decoupled from the contents of the list of types. 类型集合的循环[x for x in lst if isinstance(x, types)]不依赖于任何特定类型,因此与类型列表的内容分离。

One important use-case certainly is for type checking or filtering: 一个重要的用例肯定是类型检查或过滤:

class Foo:
    pass

lst = ["bla", 42, Foo()]
types = (str, Foo)
filtered = [x for x in lst if isinstance(x, types)]
# ['bla', <__main__.Foo at 0x7fa3422aa668>]

Another might be for dynamically creating instances of some class, eg with defaultdict . 另一个可能是动态创建某个类的实例,例如使用defaultdict

class Bar:
    def __init__(self):
        self.value = 0

from collections import defaultdict
d = defaultdict(Bar)
for x, y in [(1,1), (1,2), (2,3), (2,4)]:
    d[x].value += y
print(d[1].value) # 3

There are many possibilities. 有很多种可能性。 One could be if you have multiple classes, and you want to access the same attribute from all of them. 如果您有多个类,并且您希望从所有类中访问相同的属性,则可能就是这样。

For example: 例如:

classes = [Class1, Class2, Class3]

for c in classes:
    print(c.__dict__)

The only possible reason I can think of is that you will call the constructor multiple times. 我能想到的唯一可能的原因是你会多次调用构造函数。 So, instead of 所以,而不是

x1 = foo()
x2 = foo()
x3 = foo()

you can write 你可以写

cls = foo
x1 = cls()
x2 = cls()
x3 = cls()

So, you can only change cls=foo with cls=bar , and the rest needs no changes. 因此,您只能使用cls=bar更改cls=foo ,其余部分不需要更改。

However, this is only appropriate for code snippets, just to try something quickly. 但是,这仅适用于代码段,只是为了快速尝试。 If you actually need to do something multiple times, write a function. 如果您确实需要多次执行某些操作,请编写一个函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM