# We use the "class" statement to create a class
class Human:

    species = "H. sapiens"
  • 类的属性attribute,被所有实例共享
    def __init__(self, name):
        # Assign the argument to the instance's name attribute
        self.name = name

        # Initialize property
        self._age = 0   
  • 构造函数里面的变量才是每个对象独有的属性
  • 前面带下划线的属性提示这是一个私有属性,只在类的内部方法使用(但是python……你懂的,只是建议)
    def say(self, msg):
        print("{name}: {message}".format(name=self.name, message=msg))
  • 实例方法第一个参数是实例本身,可以访问实例的属性和方法
    # A class method is shared among all instances
    # They are called with the calling class as the first argument
    @classmethod
    def get_species(cls):
        return cls.species
  • 类方法第一个参数是类本身,可以访问类的属性和方法
    # A static method is called without a class or instance reference
    @staticmethod
    def grunt():
        return "*grunt*"
  • 静态方法,不依赖于实例或类,可以像普通函数一样被调用,但它们属于类的命名空间,而不是类的实例。
  • 静态方法与类相关联,但是关联性最弱 -可以直接通过类名来调用它,而不需要创建类的实例。

对于实例内部私有属性的方法

    # A property is just like a getter.
    # It turns the method age() into a read-only attribute of the same name.
    # There's no need to write trivial getters and setters in Python, though.
    @property
    def age(self):
        return self._age
  • @property 装饰器装饰的方法,可以像属性一样访问,但是不能像方法一样调用。
  • 但是可以通过属性名来调用它,这就是为什么我们可以用 obj.age 来访问对象的年龄,而不需要obj.get_age()
    # This allows the property to be set
    @age.setter
    def age(self, age):
        self._age = age

    # This allows the property to be deleted
    @age.deleter
    def age(self):
        del self._age

使用名字空间判断语句在程序启动时自动创建实例

# When a Python interpreter reads a source file it executes all its code.
# This __name__ check makes sure this code block is only executed when this
# module is the main program.
if __name__ == "__main__":
    # Instantiate a class
    i = Human(name="Ian")
    i.say("hi")                     # "Ian: hi"
    j = Human("Joel")
    j.say("hello")                  # "Joel: hello"
    # i and j are instances of type Human; i.e., they are Human objects.

    # Call our class method
    i.say(i.get_species())          # "Ian: H. sapiens"
    # Change the shared attribute
    Human.species = "H. neanderthalensis"
    i.say(i.get_species())          # => "Ian: H. neanderthalensis"
    j.say(j.get_species())          # => "Joel: H. neanderthalensis"

    # Call the static method
    print(Human.grunt())            # => "*grunt*"

    # Static methods can be called by instances too
    print(i.grunt())                # => "*grunt*"

    # Update the property for this instance
    i.age = 42
    # Get the property
    i.say(i.age)                    # => "Ian: 42"
    j.say(j.age)                    # => "Joel: 0"
    # Delete the property
    del i.age

实现迭代器

  • 实现“迭代器协议”,在类中定义__iter__() 函数和__next__()函数
class Fibonacci:
    def __init__(self, n):
        self.n = n
        self.a, self.b = 0, 1

    def __iter__(self):
        return self

    def __next__(self):
        fib = self.a
        if fib > self.n:
            raise StopIteration
        self.a, self.b = self.b, self.a + self.b
        return fib
  • 实现“迭代器协议”的类,必须实现两个方法:__iter__()__next__()
  • __iter__() 方法返回一个迭代器对象,该对象实现了 __next__() 方法。
  • __next__() 方法返回迭代器的下一个值,或者在迭代结束时引发 StopIteration 异常。
  • 迭代器对象可以被用于 for 循环,或者用 next() 函数来获取下一个值。
fib = Fibonacci(100)
for num in fib:
    print(num)

类的继承与封装

等有需要再来学吧

类与对象的一些用法

使用类封装全局变量