Intermediate Python 📂 Class and Object · 2 of 10 209 min read

Python OOP — Instance Methods, Class Variables & Class Methods

Master the three tools that make Python classes actually powerful: instance methods that act on a single object, class variables that share state across every instance, and class methods that own the class itself — perfect for alternate constructors like from_csv and class-wide operations. A coffee-shop-chain analogy, three animated SVG diagrams, the shadow-attribute trap, the mutable-class-variable trap, and 10 golden rules.

🌐
SectionSection第 01 节

The Story That Explains These Three Tools ☕इन तीन Tools को समझाने वाली कहानी ☕一个讲清这三个工具的故事 ☕

The Coffee Shop Chain — "Bean There"Coffee Shop Chain — "Bean There"咖啡连锁店 —— "Bean There"
You own Bean There, a coffee-shop chain with 200 stores around the world.

Each store has its own cash register, its own daily revenue and its own baristas. These are instance variables — different for every store.

But every store shares the same menu, the same prices and the same logo. These are class variables — one truth for the whole chain.

When a customer orders a latte in Mumbai, only the Mumbai store's revenue moves. That is an instance method — behaviour that runs on one store. When HQ raises the latte price from $4.50 to $5.00, every store has the new price at once. That is a class method — one call, the whole chain updates.
आप Bean There के मालिक हैं — दुनिया भर में 200 stores वाली coffee-shop chain।

हर store का अपना cash register, अपना रोज़ का revenue और अपने baristas हैं। ये instance variables हैं — हर store के लिए अलग।

पर हर store का menu, prices और logo एक ही है। ये class variables हैं — पूरी chain के लिए एक ही सच।

जब Mumbai में कोई customer latte मँगाता है, तो सिर्फ़ Mumbai store का revenue बदलता है। यह instance method है — एक store पर चलने वाला व्यवहार। जब HQ latte की price $4.50 से $5.00 करता है, तो हर store पर नई price तुरंत लागू हो जाती है। यह class method है — एक call, पूरी chain update।
你经营着 Bean There,一家在全世界有 200 家门店的咖啡连锁店。

每家店都有自己的收银机、自己的日营业额和自己的咖啡师。这些是 实例变量 — 每家店各不相同。

但所有门店共用同一份菜单、同样的价格和同一个标志。这些是 类变量 — 整个连锁只有一份。

顾客在孟买店点一杯拿铁,只有孟买店的营业额变化。这就是 实例方法 — 作用于某一家店的行为。总部把拿铁从 $4.50 提价到 $5.00,所有门店立刻生效。这就是 类方法 — 一次调用,整个连锁都更新。
🌟
The Three Tools in One Sentenceतीनों Tools एक वाक्य में一句话说清三个工具

Instance methods = behaviour of one object. Class variables = data shared by every object. Class methods = behaviour that acts on the class itself (or creates new objects). Master these three and you can model almost any real-world problem in Python.

Instance methods = एक object का व्यवहार। Class variables = हर object का साझा data। Class methods = ख़ुद class पर काम करने वाला व्यवहार (या नए objects बनाने वाला)। इन तीनों में माहिर हो जाएँ, तो आप Python में लगभग हर असली समस्या को model कर सकते हैं।

实例方法 = 单个对象的行为。类变量 = 所有对象共享的数据。类方法 = 作用于类本身的行为(或用于创建新对象)。掌握这三者,你几乎能用 Python 为任何现实问题建模。

▶️
This Tutorial Has Four Simulators and a Quizइस Tutorial में चार Simulators और एक Quiz है本教程有四个模拟器和一个小测验

Look for the interactive boxes: the Attribute Lookup Lab (Section 05), Who Receives What? (06), the Coffee Chain Simulator (09) and the Bug Doctor (11). The lab and the chain were checked against real Python on hundreds of random runs.

Interactive डिब्बे खोजें: Attribute Lookup Lab (Section 05), किसे क्या मिलता है? (06), Coffee Chain Simulator (09) और Bug Doctor (11)। Lab और chain को सैकड़ों random runs पर असली Python से जाँचा गया।

请留意这些互动框:属性查找实验室(第 05 节)、谁接收了什么?(06)、咖啡连锁模拟器(09)和 Bug 医生(11)。实验室和连锁模拟器已在数百次随机运行中与真实 Python 核对过。


SectionSection第 02 节

Where We Are — What You Already Know 🧭हम कहाँ हैं — जो आप पहले से जानते हैं 🧭我们在哪里 — 你已经掌握的内容 🧭

You already know how to write a class with __init__ and instance variables:

आप पहले से जानते हैं कि __init__ और instance variables वाली class कैसे लिखते हैं:

你已经会写带有 __init__ 和实例变量的类了:

class CoffeeShop:
    def __init__(self, city, staff_count):
        self.city          = city          # instance variable - per store
        self.staff_count   = staff_count   # instance variable - per store
        self.daily_revenue = 0.0           # instance variable - per store

store1 = CoffeeShop("Mumbai", 8)
store2 = CoffeeShop("London", 12)
print(store1.__dict__)
print(store2.__dict__)
OUTPUT
{'city': 'Mumbai', 'staff_count': 8, 'daily_revenue': 0.0} {'city': 'London', 'staff_count': 12, 'daily_revenue': 0.0}

This gives you objects that hold data. Next we need three more things: objects that can also do things (instance methods), data that every object shares (class variables), and methods that belong to the class itself (class methods). One at a time.

इससे ऐसे objects मिलते हैं जो data रखते हैं। अब हमें तीन और चीज़ें चाहिए: ऐसे objects जो काम भी कर सकें (instance methods), ऐसा data जो हर object साझा करे (class variables), और ऐसे methods जो ख़ुद class के हों (class methods)। एक-एक करके।

这样得到的对象能 保存数据。接下来还需要三样东西:能 做事 的对象(实例方法)、所有 对象共享的数据(类变量),以及属于 类本身 的方法(类方法)。我们一个一个来。


SectionSection第 03 节

Normal Methods (Instance Methods) — Behaviour of Each Object 🛠️सामान्य Methods (Instance Methods) — हर Object का व्यवहार 🛠️普通方法(实例方法)— 每个对象的行为 🛠️

A normal method — also called an instance method — is a function written inside a class whose first parameter is self. When you call obj.method(), Python passes obj in as self, so the method knows which object it is working on.

सामान्य method — जिसे instance method भी कहते हैं — class के अंदर लिखा ऐसा function है जिसका पहला parameter self है। जब आप obj.method() बुलाते हैं, Python obj को self के रूप में भेजता है, ताकि method को पता रहे कि वह किस object पर काम कर रहा है।

普通方法(也叫 实例方法)是写在类里、第一个参数为 self 的函数。调用 obj.method() 时,Python 把 obj 作为 self 传进去,于是方法知道自己在处理哪个对象。

🛠️ Anatomy of an Instance MethodInstance Method की बनावट实例方法的结构
Definition
Written inside the class body: def serve(self, item, price): Class body के अंदर लिखा: def serve(self, item, price): 写在类体内:def serve(self, item, price):
First param
self — receives the object the method was called on self — वह object पाता है जिस पर method बुलाया गया self — 接收调用该方法的对象
Reads state
Uses self.x to read and write that object's own instance variables उस object के अपने instance variables पढ़ने-लिखने के लिए self.x 用 self.x 读写该对象自己的实例变量
Called
mumbai.serve("latte", 4.5) — Python passes mumbai as self mumbai.serve("latte", 4.5) — Python mumbai को self बनाकर भेजता है mumbai.serve("latte", 4.5) — Python 把 mumbai 作为 self 传入
class CoffeeShop:
    def __init__(self, city):
        self.city          = city
        self.daily_revenue = 0.0
        self.orders        = []

    # -- Normal (instance) method: acts on THIS store --
    def serve(self, item, price):
        self.daily_revenue += price
        self.orders.append(item)
        print(f"[{self.city}] Served {item} for ${price}")

    # -- Another instance method that reports state --
    def summary(self):
        print(f"{self.city}: {len(self.orders)} orders, ${self.daily_revenue}")

mumbai = CoffeeShop("Mumbai")
london = CoffeeShop("London")

mumbai.serve("latte", 4.5)         # self = mumbai
mumbai.serve("muffin", 3.5)        # self = mumbai
london.serve("espresso", 3.0)      # self = london

mumbai.summary()                   # uses Mumbai's data only
london.summary()                   # uses London's data only
OUTPUT
[Mumbai] Served latte for $4.5 [Mumbai] Served muffin for $3.5 [London] Served espresso for $3.0 Mumbai: 2 orders, $8.0 London: 1 orders, $3.0

Notice $4.5 and $8.0: an f-string prints a float as it is, without a fixed number of decimals. Section 09 uses :.2f to always show two.

$4.5 और $8.0 देखें: f-string float को जैसा है वैसा print करती है, तय decimals के बिना। Section 09 हमेशा दो decimals दिखाने के लिए :.2f इस्तेमाल करता है।

注意 $4.5 和 $8.0:f-string 按原样打印浮点数,不固定小数位。第 09 节用 :.2f 来始终显示两位小数。

An Instance Method Acts on One Specific ObjectInstance Method एक ख़ास Object पर काम करता है实例方法只作用于一个特定对象
An instance method acts on one objectmumbai.serve("latte", 4.5)self = mumbaimumbaidaily_revenue$0.0$4.5londondaily_revenue$0.0✓ unchanged✓ जस का तस✓ 未变tokyodaily_revenue$0.0✓ unchanged✓ जस का तस✓ 未变self points to ONE object onlyself सिर्फ़ एक object की ओर इशारा करता हैself 只指向一个对象

Python passes mumbai in as self, so only Mumbai's revenue moves. London and Tokyo are never touched.

Python mumbai को self बनाकर भेजता है, इसलिए सिर्फ़ Mumbai का revenue बदलता है। London और Tokyo को छुआ तक नहीं जाता।

Python 把 mumbai 作为 self 传入,所以只有孟买的营业额变化。伦敦和东京完全没被碰到。


SectionSection第 04 节

Class Variables — One Copy, Shared by Every Object 📋Class Variables — एक Copy, हर Object साझा करता है 📋类变量 — 只有一份,所有对象共享 📋

A class variable is written at the class level, not inside __init__. There is exactly one copy, and every instance can see it. Think of it as "facts about the idea of a coffee shop, not about any one shop".

Class variable class के स्तर पर लिखा जाता है, __init__ के अंदर नहीं। इसकी ठीक एक copy होती है, और हर instance इसे देख सकता है। इसे ऐसे सोचें: "coffee shop के विचार से जुड़े तथ्य, किसी एक shop के नहीं"।

类变量 写在类的层级上,而不是 __init__ 里。它只有一份,所有实例都能看到。可以把它理解为"属于咖啡店这个概念的事实,而不是某一家店的"。

class CoffeeShop:
    # -- Class variables: declared at the class level, ONE copy total --
    company_name = "Bean There"
    menu         = {"latte": 4.50, "espresso": 3.00, "muffin": 3.50}
    total_stores = 0

    def __init__(self, city):
        # -- Instance variables: one copy per object --
        self.city          = city
        self.daily_revenue = 0.0
        CoffeeShop.total_stores += 1     # bump the shared counter

mumbai = CoffeeShop("Mumbai")
london = CoffeeShop("London")
tokyo  = CoffeeShop("Tokyo")

# Read class variables through the class itself
print(CoffeeShop.company_name)
print(CoffeeShop.total_stores)
print(CoffeeShop.menu["latte"])

# You CAN also read them through any instance - they are shared
print(mumbai.company_name)
print(london.menu["latte"])
print(london.menu is CoffeeShop.menu)    # the very same dict object

print(mumbai.__dict__)                   # the class variables are NOT in here
OUTPUT
Bean There 3 4.5 Bean There 4.5 True {'city': 'Mumbai', 'daily_revenue': 0.0}

The last line is the key: mumbai.__dict__ holds only city and daily_revenue. When you read mumbai.company_name, Python does not find it on the object, so it looks on the class. That is why one copy is enough.

आख़िरी line सबसे अहम है: mumbai.__dict__ में सिर्फ़ city और daily_revenue हैं। जब आप mumbai.company_name पढ़ते हैं, Python को यह object पर नहीं मिलता, तो वह class पर देखता है। इसीलिए एक copy काफ़ी है।

最后一行是关键:mumbai.__dict__ 里只有 city 和 daily_revenue。读取 mumbai.company_name 时,Python 在对象上找不到,就去类上找。所以一份就够了。

🔑
Class Variable vs Instance Variable — the One-Line TestClass Variable बनाम Instance Variable — एक Line की जाँच类变量与实例变量 — 一行判断法

Class variable — one copy in total, shared. Written directly under the class line: menu = {...}. Instance variable — one copy per object. Written with self. inside a method: self.city = city.

Class variable — कुल एक copy, साझा। सीधे class line के नीचे लिखा: menu = {...}। Instance variable — हर object की एक copy। Method के अंदर self. के साथ लिखा: self.city = city।

类变量 — 总共一份,共享。直接写在 class 行下面:menu = {...}。实例变量 — 每个对象一份。在方法里用 self. 写:self.city = city。

Class Variable Is Shared, Instance Variable Is NotClass Variable साझा है, Instance Variable नहीं类变量是共享的,实例变量不是
One shared menu, three separate revenuesclass CoffeeShop · menulatte 4.5menu["latte"] = 5.0→ 5.0mumbaireads latte:5.0daily_revenue0.05.0londonreads latte:5.0daily_revenue0.0tokyoreads latte:5.0daily_revenue0.0one menu change reaches all · one sale changes one storeएक menu बदलाव सब तक · एक sale सिर्फ़ एक store改一次菜单影响所有店 · 卖一杯只影响一家店

First HQ changes the shared menu, and all three stores read 5.0. Then Mumbai sells one latte for 5.0: only Mumbai's revenue moves.

पहले HQ साझा menu बदलता है, और तीनों stores 5.0 पढ़ते हैं। फिर Mumbai 5.0 में एक latte बेचता है: सिर्फ़ Mumbai का revenue बदलता है।

先是总部修改共享菜单,三家店都读到 5.0。然后孟买以 5.0 卖出一杯拿铁:只有孟买的营业额变化。


SectionSection第 05 节

The Two Gotchas of Class Variables ⚠️Class Variables के दो जाल ⚠️类变量的两个陷阱 ⚠️

Class variables are simple — until you change them the wrong way. Two traps catch almost every beginner. Both come from one rule: reading falls back to the class, but writing through an object creates an instance variable.

Class variables आसान हैं — जब तक आप उन्हें ग़लत तरीक़े से न बदलें। दो जाल लगभग हर beginner को पकड़ते हैं। दोनों एक ही नियम से आते हैं: पढ़ते समय Python class पर जाता है, पर object के ज़रिए लिखने से instance variable बनता है।

类变量很简单 — 直到你用错误的方式修改它们。有两个陷阱几乎每个初学者都会踩。它们都来自同一条规则:读取时会退回到类上找,但通过对象写入会创建实例变量。

Gotcha #1 — Writing Through an Instance Creates a Shadowजाल #1 — Instance के ज़रिए लिखने से Shadow बनता है陷阱 #1 — 通过实例写入会产生遮蔽

class CoffeeShop:
    total_stores = 0              # class variable

s1 = CoffeeShop()
s2 = CoffeeShop()

# WRONG: this does NOT update the shared counter
s1.total_stores = 99              # creates a NEW instance variable on s1
print(s1.total_stores)            # s1's own attribute (the shadow)
print(s2.total_stores)            # s2 still reads the class variable
print(CoffeeShop.total_stores)    # the class variable is untouched
print(s1.__dict__, s2.__dict__)

# RIGHT: update through the class itself
CoffeeShop.total_stores = 50
print(s2.total_stores)            # s2 sees the new value
print(s1.total_stores)            # s1 still sees its own shadow!
OUTPUT
99 0 0 {'total_stores': 99} {} 50 99
Lookup Order: the Object First, Then the Classखोज का क्रम: पहले Object, फिर Class查找顺序:先对象,再类
Writing through an instance creates a shadowclass CoffeeShoptotal_stores = 0s1.__dict__s2.__dict__total_stores = 99SHADOW — found firstSHADOW — पहले मिलता है遮蔽 — 先被找到{} (empty)s2.total_stores → 0s1.total_stores → 99the class never sees itclass को यह दिखता ही नहीं类根本看不到它

s1 now has its own total_stores, so reading stops there. s2 has none, so Python goes on to the class.

s1 के पास अब अपना total_stores है, इसलिए पढ़ना वहीं रुक जाता है। s2 के पास नहीं है, इसलिए Python class तक जाता है।

s1 现在有了自己的 total_stores,读取就停在那里。s2 没有,于是 Python 继续去类上找。

⚠️
The Ruleनियम规则

Writing instance.attr = value always creates an instance variable — even if a class variable with the same name exists. To change a class variable, write it through the class: ClassName.attr = value.

instance.attr = value लिखने से हमेशा instance variable बनता है — भले ही उसी नाम का class variable मौजूद हो। Class variable बदलने के लिए class के ज़रिए लिखें: ClassName.attr = value।

写 instance.attr = value 总是 创建实例变量 — 即使存在同名的类变量。要修改类变量,请通过类来写:ClassName.attr = value。

Gotcha #2 — Mutable Class Variables Are Shared Stateजाल #2 — Mutable Class Variables साझा State हैं陷阱 #2 — 可变类变量是共享状态

class CoffeeShop:
    orders = []                   # class variable - a list (mutable!)

    def __init__(self, city):
        self.city = city

s1 = CoffeeShop("Mumbai")
s2 = CoffeeShop("London")

s1.orders.append("latte")         # changes the SHARED list in place
print(s1.orders)
print(s2.orders)                  # London "has" Mumbai's order!
print(s1.orders is s2.orders)     # the same list object
OUTPUT
['latte'] ['latte'] True

No = was used, so no shadow was made. .append() changed the one list that lives on the class. The fix is to create the list in __init__:

कोई = इस्तेमाल नहीं हुआ, इसलिए shadow नहीं बना। .append() ने class पर रहने वाली एक ही list बदल दी। हल है list को __init__ में बनाना:

这里没有用 =,所以没有产生遮蔽。.append() 修改了类上那唯一的列表。修正方法是在 __init__ 里创建列表:

class CoffeeShop:
    def __init__(self, city):
        self.city   = city
        self.orders = []          # FIX: a fresh list for every store

s1 = CoffeeShop("Mumbai")
s2 = CoffeeShop("London")
s1.orders.append("latte")
print(s1.orders, s2.orders, s1.orders is s2.orders)
OUTPUT
['latte'] [] False
🔥
The Fixहल修正方法

Never use a mutable object (list, dict, set) as a class variable unless you really want every instance to share and change the same one. For per-object lists, create them in __init__: self.orders = []. Use class variables for shared data that does not change in place — strings, numbers, tuples — or for things that truly belong to everyone, like the menu.

Mutable object (list, dict, set) को class variable तभी बनाएँ जब आप सच में चाहते हों कि हर instance उसी एक को साझा करे और बदले। हर object की अपनी list __init__ में बनाएँ: self.orders = []। Class variables उस साझा data के लिए रखें जो अपनी जगह नहीं बदलता — strings, numbers, tuples — या उन चीज़ों के लिए जो सच में सबकी हैं, जैसे menu।

除非你真的希望所有实例共享并修改同一个对象,否则不要把可变对象(list、dict、set)作为类变量。每个对象自己的列表应在 __init__ 里创建:self.orders = []。类变量适合不会原地修改的共享数据 — 字符串、数字、元组 — 或者真正属于所有人的东西,比如菜单。

🔬 Simulator: Attribute Lookup Lab🔬 Simulator: Attribute Lookup Lab🔬 模拟器:属性查找实验室

Click lines to run them, in any order. Each store card shows its own __dict__ (shadows in orange) and what reading each name finds — from the object itself, or from the class. The coloured tags show which list or dict is the same object. The model was checked against real Python on 400 random sequences.

Lines पर click करके उन्हें किसी भी क्रम में चलाएँ। हर store card उसका अपना __dict__ (shadows नारंगी में) और हर नाम पढ़ने पर क्या मिलता है, दिखाता है — object से या class से। रंगीन tags बताते हैं कि कौन-सी list या dict एक ही object है। Model को 400 random sequences पर असली Python से जाँचा गया।

点击代码行即可运行,顺序随意。每张店铺卡片显示它 自己的 __dict__(遮蔽以橙色显示),以及 读取 每个名字时找到的值 — 来自对象本身还是来自类。彩色标签表示哪些列表或字典是同一个对象。该模型已在 400 个随机序列上与真实 Python 核对过。

Attribute Lookup LabAttribute Lookup Lab属性查找实验室read falls back · write makes a shadowपढ़ना class तक · लिखना shadow बनाता है读取会回退 · 写入产生遮蔽
Run a line (purple = through the class, orange = through an object)एक line चलाएँ (बैंगनी = class के ज़रिए, नारंगी = object के ज़रिए)运行一行(紫色 = 通过类,橙色 = 通过对象)
Lines run so farअब तक चली lines已运行的代码

SectionSection第 06 节

Class Methods — Methods That Belong to the Class 🏛️Class Methods — Class के अपने Methods 🏛️类方法 — 属于类本身的方法 🏛️

A class method is a method whose first parameter is the class itself — named cls by convention — not an object. You mark it with the @classmethod decorator on the line above def. You usually call it on the class: CoffeeShop.from_csv(...).

Class method ऐसा method है जिसका पहला parameter ख़ुद class होती है — परंपरा से cls नाम — कोई object नहीं। इसे def के ऊपर वाली line पर @classmethod decorator से चिह्नित करते हैं। आमतौर पर इसे class पर बुलाते हैं: CoffeeShop.from_csv(...)।

类方法 的第一个参数是类本身 — 按惯例命名为 cls — 而不是对象。在 def 上一行加 @classmethod 装饰器来标记它。通常在类上调用它:CoffeeShop.from_csv(...)。

Three very common uses:

तीन बहुत आम इस्तेमाल:

三种非常常见的用途:

🏗️
Alternate ConstructorAlternate Constructor备用构造器
factory
A second way to create an object. CoffeeShop.from_csv("Mumbai,8") splits a text row and returns a new store. The parsing stays with the class.
Object बनाने का दूसरा तरीक़ा। CoffeeShop.from_csv("Mumbai,8") text row को तोड़कर नया store लौटाता है। Parsing class के साथ रहती है।
创建对象的第二种方式。CoffeeShop.from_csv("Mumbai,8") 拆分一行文本并返回一家新店。解析逻辑与类放在一起。
📣
Class-Wide Operationपूरी Class का काम全类操作
affects everyoneसब पर असर影响所有人
Changes shared state, not one object. CoffeeShop.update_price("latte", 5.00) raises the price for the whole chain.
साझा state बदलता है, किसी एक object को नहीं। CoffeeShop.update_price("latte", 5.00) पूरी chain की price बढ़ाता है।
修改共享状态,而不是某一个对象。CoffeeShop.update_price("latte", 5.00) 为整个连锁提价。
📊
Aggregate QueryAggregate Query汇总查询
no object neededobject की ज़रूरत नहीं无需对象
Answers a question about the class as a whole. CoffeeShop.how_many_open() returns the store count without needing any one store.
पूरी class के बारे में सवाल का जवाब देता है। CoffeeShop.how_many_open() किसी एक store के बिना store count लौटाता है।
回答关于整个类的问题。CoffeeShop.how_many_open() 不需要任何一家店就能返回门店数量。
class CoffeeShop:
    company_name = "Bean There"
    menu         = {"latte": 4.50, "espresso": 3.00}
    total_stores = 0

    def __init__(self, city, staff_count):
        self.city          = city
        self.staff_count   = staff_count
        self.daily_revenue = 0.0
        CoffeeShop.total_stores += 1

    # -- Class method as an ALTERNATE CONSTRUCTOR --
    @classmethod
    def from_csv(cls, row: str):
        """Build a CoffeeShop from a CSV row like 'Mumbai,8'."""
        city, staff = row.split(",")
        return cls(city, int(staff))       # cls(...) is CoffeeShop(...) here

    # -- Class method for a CLASS-WIDE OPERATION --
    @classmethod
    def update_price(cls, item, new_price):
        """HQ raises a price everywhere at once."""
        cls.menu[item] = new_price
        print(f"HQ: {item} is now ${new_price} at every store")

    # -- Class method for an AGGREGATE QUERY --
    @classmethod
    def how_many_open(cls):
        return cls.total_stores

mumbai = CoffeeShop("Mumbai", 8)                 # regular constructor
london = CoffeeShop.from_csv("London,12")        # alternate constructor
tokyo  = CoffeeShop.from_csv("Tokyo,20")

CoffeeShop.update_price("latte", 5.00)           # class-wide operation

print(CoffeeShop.how_many_open())                # aggregate query
print(mumbai.menu["latte"])                      # Mumbai sees the update
print(london.city, london.staff_count, type(london).__name__)
print(mumbai.how_many_open())                    # also works through an object
OUTPUT
HQ: latte is now $5.0 at every store 3 5.0 London 12 CoffeeShop 3

The last line shows that a class method can also be called through an object. Python still passes the class as cls.

आख़िरी line दिखाती है कि class method को object के ज़रिए भी बुला सकते हैं। Python फिर भी cls के रूप में class ही भेजता है।

最后一行表明,类方法也可以通过对象调用。Python 仍然把 类 作为 cls 传入。

self Points to One Object · cls Points to the Classself एक Object की ओर · cls Class की ओरself 指向一个对象 · cls 指向类
self vs clsINSTANCE METHODINSTANCE METHOD实例方法CLASS METHODCLASS METHOD类方法mumbai.serve("latte")CoffeeShop.from_csv("Paris,6")self =the mumbai objectrevenue 0 → 4.5works on ONE existing objectएक मौजूदा object पर काम作用于一个已有对象cls =class CoffeeShopnew: pariscls(...) builds a fresh objectcls(...) नया object बनाता हैcls(...) 创建一个新对象

self answers "which object am I working on?". cls answers "which class am I working on?".

self बताता है "मैं किस object पर काम कर रहा हूँ?"। cls बताता है "मैं किस class पर काम कर रहा हूँ?"।

self 回答"我在处理哪个对象?";cls 回答"我在处理哪个类?"。

🎯 Simulator: Who Receives What?🎯 Simulator: किसे क्या मिलता है?🎯 模拟器:谁接收了什么?

Pick a call. The card that lands in the first parameter lights up with a self or cls badge, and the method's def line is highlighted. Each call starts from the same three stores and was recorded from a real Python run. (The PremiumCoffeeShop call is explained in Section 07.)

कोई call चुनें। पहले parameter में पहुँचने वाला card self या cls badge के साथ चमकता है, और method की def line हाइलाइट होती है। हर call उन्हीं तीन stores से शुरू होती है और असली Python run से रिकॉर्ड की गई। (PremiumCoffeeShop वाली call Section 07 में समझाई गई है।)

选一个调用。进入第一个参数的那张卡片会亮起 self 或 cls 标记,方法的 def 行也会高亮。每个调用都从同样的三家店开始,并由真实 Python 运行记录。(PremiumCoffeeShop 的调用在第 07 节解释。)

Who Receives What?किसे क्या मिलता है?谁接收了什么?self = an object · cls = a classself = एक object · cls = एक classself = 对象 · cls = 类
The method that runsजो method चलता है被运行的方法
Real outputअसली output真实输出

SectionSection第 07 节

Why cls and Not Just CoffeeShop? 🧬cls क्यों, सीधे CoffeeShop क्यों नहीं? 🧬为什么用 cls 而不直接写 CoffeeShop?🧬

Inside a class method you could type the class name directly. But cls always means the class the method was actually called on. That matters when another class is built from this one (a subclass — a topic of its own, coming later). Here is the difference in one run:

Class method के अंदर आप class का नाम सीधे लिख सकते हैं। पर cls का मतलब हमेशा वह class है जिस पर method असल में बुलाया गया। यह तब मायने रखता है जब इस class से कोई दूसरी class बनाई जाए (subclass — यह अपना अलग topic है, आगे आएगा)। एक run में फ़र्क़ देखें:

在类方法里,你 可以 直接写类名。但 cls 永远表示方法 实际被调用 的那个类。当另一个类由这个类派生出来时(子类 — 这是单独的主题,以后会讲),这一点就很重要。看一次运行就明白了:

class CoffeeShop:
    company_name = "Bean There"

    def __init__(self, city, staff_count):
        self.city        = city
        self.staff_count = staff_count

    @classmethod
    def from_csv(cls, row):
        city, staff = row.split(",")
        return cls(city, int(staff))    # uses cls, not CoffeeShop

class PremiumCoffeeShop(CoffeeShop):    # a subclass
    company_name = "Bean There Premium"

# Because from_csv uses cls, this returns a PremiumCoffeeShop
p = PremiumCoffeeShop.from_csv("Milan,10")
print(type(p).__name__)
print(p.company_name)
print(p.city, p.staff_count)
OUTPUT
PremiumCoffeeShop Bean There Premium Milan 10

Now the same code with the class name typed in by hand:

अब वही code, class का नाम हाथ से लिखा हुआ:

再看同样的代码,但手动写死类名:

class CoffeeShop:
    company_name = "Bean There"

    def __init__(self, city, staff_count):
        self.city        = city
        self.staff_count = staff_count

    @classmethod
    def from_csv(cls, row):
        city, staff = row.split(",")
        return CoffeeShop(city, int(staff))    # hard-coded class name

class PremiumCoffeeShop(CoffeeShop):
    company_name = "Bean There Premium"

p = PremiumCoffeeShop.from_csv("Milan,10")
print(type(p).__name__)                         # the wrong type!
print(p.company_name)
OUTPUT
CoffeeShop Bean There
💡
The Habitआदत好习惯

Inside a @classmethod, always use cls — never the typed class name. It costs nothing and keeps your class working correctly with future subclasses.

@classmethod के अंदर हमेशा cls इस्तेमाल करें — कभी लिखा हुआ class नाम नहीं। इसमें कोई ख़र्च नहीं, और आपकी class आगे की subclasses के साथ सही चलती है।

在 @classmethod 里始终使用 cls — 不要写死类名。这毫无成本,还能让你的类与将来的子类正确配合。


SectionSection第 08 节

Instance Method vs Class Method — At a Glance 👀Instance Method बनाम Class Method — एक नज़र में 👀实例方法与类方法 — 一览对比 👀

Questionसवाल问题Instance methodInstance method实例方法Class methodClass method类方法
Decorator needed?Decorator चाहिए?需要装饰器?Noनहीं不需要@classmethod
First parameterपहला parameter第一个参数self — the objectself — objectself — 对象cls — the classcls — classcls — 类
Called viaकैसे बुलाते हैं调用方式obj.method()Class.method() (or obj.method())Class.method() (या obj.method())Class.method()(或 obj.method())
Needs an existing object?मौजूदा object चाहिए?需要已有对象?Yesहाँ需要Noनहीं不需要
Read/write instance variables?Instance variables पढ़/लिख सकता है?能读写实例变量?Yes — via self.xहाँ — self.x से能 — 通过 self.xNo — there is no selfनहीं — self नहीं है不能 — 没有 self
Read/write class variables?Class variables पढ़/लिख सकता है?能读写类变量?Read yes; write through the class nameपढ़ना हाँ; लिखना class के नाम से可以读;写要通过类名Yes — via cls.xहाँ — cls.x से能 — 通过 cls.x
Creates new objects?नए objects बनाता है?创建新对象?Rarely — not its jobकम ही — यह उसका काम नहीं很少 — 不是它的职责Often — return cls(...)अक्सर — return cls(...)经常 — return cls(...)
Typical useआम इस्तेमाल典型用途Behaviour of this one objectइसी एक object का व्यवहार这一个对象的行为Alternate constructor, class-wide change, aggregate queryAlternate constructor, पूरी class का बदलाव, aggregate query备用构造器、全类修改、汇总查询

SectionSection第 09 节

Complete Practical Example — All Three Together ☕पूरा व्यावहारिक उदाहरण — तीनों एक साथ ☕完整实例 — 三者合一 ☕

One class that uses instance methods, class variables and class methods in a small, realistic example. Paste it, run it, and read it line by line.

एक class जो instance methods, class variables और class methods को एक छोटे, असली उदाहरण में इस्तेमाल करती है। Paste करें, चलाएँ, और line-by-line पढ़ें।

一个在小而真实的例子里同时使用实例方法、类变量和类方法的类。粘贴、运行,然后逐行阅读。

class CoffeeShop:
    # == CLASS VARIABLES - shared across every store ==
    company_name = "Bean There"
    menu         = {"latte": 4.50, "espresso": 3.00, "muffin": 3.50}
    tax_rate     = 0.10
    total_stores = 0

    def __init__(self, city, staff_count):
        # == INSTANCE VARIABLES - one copy per store ==
        self.city          = city
        self.staff_count   = staff_count
        self.daily_revenue = 0.0
        self.orders        = []               # a fresh list per store
        CoffeeShop.total_stores += 1

    # == INSTANCE METHOD - acts on THIS store ==
    def serve(self, item):
        if item not in CoffeeShop.menu:
            raise ValueError(f"{item} not on menu")
        price = CoffeeShop.menu[item] * (1 + CoffeeShop.tax_rate)
        self.daily_revenue += price
        self.orders.append(item)
        print(f"[{self.city}] Served {item} for ${price:.2f}")

    # == INSTANCE METHOD - reports THIS store's state ==
    def report(self):
        print(f"{self.city:8s}  orders={len(self.orders):2d}  "
              f"revenue=${self.daily_revenue:7.2f}")

    # == CLASS METHOD - alternate constructor ==
    @classmethod
    def from_csv(cls, row: str):
        city, staff = row.split(",")
        return cls(city.strip(), int(staff))

    # == CLASS METHOD - HQ changes shared state ==
    @classmethod
    def update_price(cls, item, new_price):
        cls.menu[item] = new_price
        print(f"HQ: {item} is now ${new_price:.2f} everywhere")

    # == CLASS METHOD - aggregate query ==
    @classmethod
    def chain_stats(cls):
        return f"{cls.company_name}: {cls.total_stores} stores open"

# -- Open three stores - two ways --
mumbai = CoffeeShop("Mumbai", 8)                # normal constructor
london = CoffeeShop.from_csv("London, 12")      # class-method constructor
tokyo  = CoffeeShop.from_csv("Tokyo, 20")

# -- Serve some drinks (instance methods on each store) --
mumbai.serve("latte")
mumbai.serve("muffin")
london.serve("espresso")
tokyo.serve("latte")

# -- HQ raises the latte price (class method -> class variable) --
CoffeeShop.update_price("latte", 5.00)
tokyo.serve("latte")    # now costs $5.00 + tax

print()
for store in (mumbai, london, tokyo):
    store.report()
print()
print(CoffeeShop.chain_stats())
OUTPUT
[Mumbai] Served latte for $4.95 [Mumbai] Served muffin for $3.85 [London] Served espresso for $3.30 [Tokyo] Served latte for $4.95 HQ: latte is now $5.00 everywhere [Tokyo] Served latte for $5.50 Mumbai orders= 2 revenue=$ 8.80 London orders= 1 revenue=$ 3.30 Tokyo orders= 2 revenue=$ 10.45 Bean There: 3 stores open

The two empty lines in the output come from the two bare print() calls. Note the prices: 4.50 × 1.1 = 4.95, and after the price change 5.00 × 1.1 = 5.50.

Output की दो ख़ाली lines दो ख़ाली print() calls से आती हैं। Prices देखें: 4.50 × 1.1 = 4.95, और price बदलने के बाद 5.00 × 1.1 = 5.50।

输出中的两个空行来自两次空的 print() 调用。看看价格:4.50 × 1.1 = 4.95,调价后 5.00 × 1.1 = 5.50。

☕ Simulator: Run the Coffee Chain☕ Simulator: Coffee Chain चलाएँ☕ 模拟器:经营咖啡连锁

This is the class above, live. Serve drinks at any store, change a price at HQ, open a new store from a CSV row, then print the reports. Watch which card lights up: a store (self) or the class (cls). Every output line matches real Python — checked on 300 random sequences.

यह ऊपर वाली class है, live। किसी भी store पर drinks serve करें, HQ पर price बदलें, CSV row से नया store खोलें, फिर reports print करें। देखें कौन-सा card चमकता है: कोई store (self) या class (cls)। हर output line असली Python से मिलती है — 300 random sequences पर जाँची गई।

这就是上面那个类,实时运行。在任意门店出售饮品,在总部改价,用 CSV 行开新店,然后打印报告。留意哪张卡片亮起:某家店(self)还是类(cls)。每一行输出都与真实 Python 一致 — 已在 300 个随机序列上核对。

Coffee Chain SimulatorCoffee Chain Simulator咖啡连锁模拟器instance methods + class methodsinstance methods + class methods实例方法 + 类方法
serve()
@classmethod
@classmethod
ConsoleConsole控制台
🏆
Notice What Just Happenedदेखिए अभी क्या हुआ注意刚才发生了什么

Every store served its own orders and kept its own revenue (instance methods, instance variables). They all read one shared menu and one shared tax rate (class variables). HQ raised the latte price with one call (a class method changing a class variable). Creating stores with from_csv and reporting with chain_stats ran on the class itself — no store needed.

हर store ने अपने orders serve किए और अपना revenue रखा (instance methods, instance variables)। सबने एक साझा menu और एक साझा tax rate पढ़ा (class variables)। HQ ने एक call से latte की price बढ़ाई (class method ने class variable बदला)। from_csv से stores बनाना और chain_stats से report करना ख़ुद class पर चला — किसी store की ज़रूरत नहीं।

每家店处理自己的订单、记录自己的营业额(实例方法、实例变量)。它们都读取同一份菜单和同一个税率(类变量)。总部一次调用就给拿铁提了价(类方法修改类变量)。用 from_csv 开店、用 chain_stats 汇总,都直接在类上运行 — 不需要任何门店。


SectionSection第 10 节

When to Use Which — Decision Grid 🧭कब कौन-सा — Decision Grid 🧭何时用哪个 — 决策表 🧭

👤
Use an Instance Method When…Instance Method तब, जब…用实例方法,当……
first parameter: selfपहला parameter: self第一个参数:self
The behaviour needs data of one object: "this account's balance", "this store's revenue", "this student's marks". Most methods you write will be instance methods.
व्यवहार को एक object का data चाहिए: "इस account का balance", "इस store का revenue", "इस student के marks"। आपके लिखे ज़्यादातर methods instance methods होंगे।
该行为需要 某一个 对象的数据:"这个账户的余额"、"这家店的营业额"、"这个学生的分数"。你写的大多数方法都是实例方法。
📚
Use a Class Variable When…Class Variable तब, जब…用类变量,当……
one copy, sharedएक copy, साझा一份,共享
The value is the same for every object: settings, shared reference data, a "how many exist" counter. Prefer types that do not change in place (str, int, tuple).
Value हर object के लिए एक ही है: settings, साझा reference data, "कितने हैं" वाला counter। ऐसे types चुनें जो अपनी जगह नहीं बदलते (str, int, tuple)।
这个值对所有对象都一样:配置、共享的参考数据、"一共有多少个"的计数器。优先使用不会原地修改的类型(str、int、tuple)。
🏗️
Class Method as Alternate ConstructorAlternate Constructor के रूप में Class Method类方法作备用构造器
factory
You want more than one way to build an object — from_csv, from_dict, today(). The parsing stays where the class lives.
आप object बनाने के एक से ज़्यादा तरीक़े चाहते हैं — from_csv, from_dict, today()। Parsing वहीं रहती है जहाँ class है।
你想要不止一种创建对象的方式 — from_csv、from_dict、today()。解析逻辑留在类所在的地方。
📡
Class Method for Class-Wide Changesपूरी Class के बदलाव के लिए Class Method类方法用于全类修改
cls.something = new
You change shared state that affects every object — a shared price, a shared setting. It says "this is a policy change, not one object's business".
आप ऐसी साझा state बदलते हैं जो हर object पर असर डाले — साझा price, साझा setting। यह बताता है "यह नीति का बदलाव है, किसी एक object का मामला नहीं"।
你修改影响所有对象的共享状态 — 共享价格、共享设置。它表明"这是政策变更,不是某个对象的事"。
❌
Don't Use a Class Method as a Regular MethodClass Method को सामान्य Method की तरह न लें不要把类方法当普通方法用
need self? not classmethodself चाहिए? classmethod नहीं需要 self?就别用 classmethod
If the method reads or writes one object's data, it must be an instance method. Adding @classmethod because it "looks neater" takes away self.
अगर method किसी एक object का data पढ़ता या लिखता है, तो वह instance method ही होना चाहिए। "साफ़ दिखता है" इसलिए @classmethod लगाने से self छिन जाता है।
如果方法要读写某一个对象的数据,它就必须是实例方法。因为"看起来更整洁"而加上 @classmethod,会让你失去 self。
❌
Don't Assign a Class Variable Through an InstanceInstance के ज़रिए Class Variable न बदलें不要通过实例给类变量赋值
shadow trapshadow का जाल遮蔽陷阱
self.total_stores = 99 makes a shadow, not an update. Write ClassName.total_stores = 99, or cls.total_stores inside a class method.
self.total_stores = 99 update नहीं, shadow बनाता है। ClassName.total_stores = 99 लिखें, या class method के अंदर cls.total_stores।
self.total_stores = 99 产生的是遮蔽,而不是更新。请写 ClassName.total_stores = 99,或在类方法里写 cls.total_stores。

SectionSection第 11 节

Common Mistakes (and Fixes) 🩹आम ग़लतियाँ (और उनके हल) 🩹常见错误(及修正)🩹

Mistakeग़लती错误What goes wrongक्या बिगड़ता है会出什么问题Fixहल修正
Forgetting self in a methodMethod में self भूलना方法里忘写 selfTypeError: ... takes 0 positional arguments but 1 was givenAdd self as the first parameterपहले parameter के रूप में self जोड़ें把 self 加为第一个参数
self.total = 99 to update a class variableClass variable बदलने के लिए self.total = 99用 self.total = 99 更新类变量Makes a shadow on that object — others unchangedउस object पर shadow बनता है — बाक़ी नहीं बदलते在该对象上产生遮蔽 — 其他对象不变ClassName.total = 99
Mutable class variable (orders = [])Mutable class variable (orders = [])可变类变量(orders = [])Every object shares it — one .append() hits allहर object साझा करता है — एक .append() सब पर所有对象共享 — 一次 .append() 影响全部Create self.orders = [] in __init____init__ में self.orders = [] बनाएँ在 __init__ 中创建 self.orders = []
Forgetting @classmethod@classmethod भूलना忘写 @classmethodIt becomes a normal method — on the class, your first argument lands in clsयह सामान्य method बन जाता है — class पर, आपका पहला argument cls में चला जाता है它变成普通方法 — 在类上调用时,你的第一个参数落进 clsAdd @classmethod on the line aboveऊपर वाली line पर @classmethod जोड़ें在上一行加 @classmethod
Hard-coding the class name inside a class methodClass method में class का नाम hard-code करना在类方法里写死类名Subclasses get the wrong typeSubclasses को ग़लत type मिलता है子类得到错误的类型Use cls — that is why it is therecls इस्तेमाल करें — वह इसी लिए है使用 cls — 它就是为此存在的
Writing self.method without ()() के बिना self.method लिखना写 self.method 却漏了 ()You get the bound method object, not its resultनतीजे की जगह bound method object मिलता है得到的是绑定方法对象,而不是结果Add the parentheses: self.method()Parentheses जोड़ें: self.method()加上括号:self.method()
A @classmethod that never uses clsऐसा @classmethod जो cls कभी इस्तेमाल न करे从不使用 cls 的 @classmethodProbably the wrong toolशायद ग़लत tool可能用错了工具Use cls, or rethink it (@staticmethod is covered in a later tutorial)cls इस्तेमाल करें, या दोबारा सोचें (@staticmethod आगे के tutorial में)使用 cls,或重新考虑(@staticmethod 将在后续教程讲解)
class Shop:
    total = 0
    def hello():                      # forgot self
        print("hi")

try:
    Shop().hello()
except TypeError as e:
    print("1. TypeError:", e)

class Shop2:
    def __init__(self, city):
        self.city = city
    def from_csv(cls, row):           # forgot @classmethod
        return cls(row)

try:
    Shop2.from_csv("Mumbai")
except TypeError as e:
    print("2. TypeError:", e)

class Shop3:
    def __init__(self, city):
        self.city = city
    def label(self):
        return self.city.upper()

s = Shop3("Pune")
print("3.", s.label)                  # forgot the ()
print("3. fixed:", s.label())
OUTPUT
1. TypeError: Shop.hello() takes 0 positional arguments but 1 was given 2. TypeError: Shop2.from_csv() missing 1 required positional argument: 'row' 3. <bound method Shop3.label of <__main__.Shop3 object at 0x7fe056736cf0>> 3. fixed: PUNE

🩺 Simulator: Bug Doctor🩺 Simulator: Bug Doctor🩺 模拟器:Bug 医生

Pick a mistake. The buggy version is on the left, the fixed one on the right, with the changed lines marked. Both outputs are real. Note that three of the six bugs give no error at all — they just quietly give wrong results.

कोई ग़लती चुनें। बाईं ओर buggy version है, दाईं ओर ठीक किया हुआ, बदली हुई lines चिह्नित। दोनों outputs असली हैं। ध्यान दें: छह में से तीन bugs कोई error नहीं देते — बस चुपचाप ग़लत नतीजे देते हैं।

选一个错误。左边是有 bug 的版本,右边是修正后的版本,改动的行已标出。两边的输出都是真实的。注意:六个 bug 中有三个 完全不报错 — 只是悄悄给出错误结果。

Bug DoctorBug DoctorBug 医生6 bugs · real outputs6 bugs · असली outputs6 个 bug · 真实输出
❌ BuggyBuggy有 bug
✅ Fixedठीक किया已修正

SectionSection第 12 节

Quick Reference 📋Quick Reference 📋速查表 📋

Taskकाम任务SyntaxSyntax语法Notesनोट说明
Define an instance methodInstance method define करना定义实例方法def serve(self, item):First parameter is always selfपहला parameter हमेशा self第一个参数永远是 self
Call an instance methodInstance method बुलाना调用实例方法store.serve("latte")Python passes store as selfPython store को self बनाकर भेजता हैPython 把 store 作为 self 传入
Read an instance variable insideअंदर instance variable पढ़ना在内部读取实例变量self.cityThis object's own dataइसी object का अपना data这个对象自己的数据
Declare a class variableClass variable declare करना声明类变量menu = {...} under the class lineclass line के नीचे menu = {...}在 class 行下写 menu = {...}One copy, shared by every objectएक copy, हर object साझा करता है一份,所有对象共享
Read a class variableClass variable पढ़ना读取类变量ClassName.menu or self.menuClassName.menu या self.menuClassName.menu 或 self.menuBoth work for readingपढ़ने के लिए दोनों चलते हैं读取时两者都可以
Change a class variableClass variable बदलना修改类变量ClassName.total = ... or ClassName.menu["x"] = ...ClassName.total = ... या ClassName.menu["x"] = ...ClassName.total = ... 或 ClassName.menu["x"] = ...Never self.total = ... (shadow)self.total = ... कभी नहीं (shadow)永远不要 self.total = ...(遮蔽)
Define a class methodClass method define करना定义类方法@classmethod + def m(cls, ...):Decorator on the line above defDecorator def के ऊपर वाली line पर装饰器写在 def 上一行
Alternate constructorAlternate constructor备用构造器return cls(...)Use cls, not the class nameClass का नाम नहीं, cls用 cls,不要写类名
Call a class methodClass method बुलाना调用类方法ClassName.from_csv("...")No object neededObject की ज़रूरत नहीं不需要对象
Count objectsObjects गिनना统计对象数Add to a class variable in __init____init__ में class variable बढ़ाएँ在 __init__ 里累加类变量ClassName.total += 1
🔎
One Subtle Pointएक बारीक बात一个细节

self.menu = {...} (attribute assignment) makes a shadow. But self.menu["latte"] = 6.0 (item assignment) does not — it changes the shared dict that self.menu finds. It works, but it hides the fact that you are changing everyone's menu. Write CoffeeShop.menu[...] so the intent is clear. Try both in the Lookup Lab (Section 05).

self.menu = {...} (attribute assignment) shadow बनाता है। पर self.menu["latte"] = 6.0 (item assignment) नहीं बनाता — यह वह साझा dict बदलता है जो self.menu को मिलती है। यह चलता है, पर छिपा देता है कि आप सबका menu बदल रहे हैं। इरादा साफ़ रखने के लिए CoffeeShop.menu[...] लिखें। Lookup Lab (Section 05) में दोनों आज़माएँ।

self.menu = {...}(属性赋值)会产生遮蔽。但 self.menu["latte"] = 6.0(元素赋值)不会 — 它修改的是 self.menu 找到的共享字典。这样能运行,但掩盖了你在修改 所有人 菜单的事实。写成 CoffeeShop.menu[...] 意图才清楚。可以在查找实验室(第 05 节)里试试两者。


SectionSection第 13 节

Golden Rules and Quiz 🏆सुनहरे नियम और Quiz 🏆黄金法则与小测验 🏆

🛡️ Methods, Class Variables and Class Methods — Rules to RememberMethods, Class Variables और Class Methods — याद रखने वाले नियम方法、类变量与类方法 — 必须记住的规则
1
A method's first parameter tells you what it works on: self = one object, cls = the class itself.
Method का पहला parameter बताता है कि वह किस पर काम करता है: self = एक object, cls = ख़ुद class।
方法的第一个参数说明它作用于什么:self = 一个对象,cls = 类本身。
2
Most of your methods should be instance methods. Use @classmethod only when you do not need self — usually an alternate constructor, a class-wide change, or an aggregate query.
आपके ज़्यादातर methods instance methods होने चाहिए। @classmethod तभी लें जब self की ज़रूरत न हो — आमतौर पर alternate constructor, पूरी class का बदलाव, या aggregate query।
你的大多数方法都应该是实例方法。 只有不需要 self 时才用 @classmethod — 通常是备用构造器、全类修改或汇总查询。
3
Class variables are for values every object truly shares — settings, shared reference data, a counter. If each object needs its own copy, put it in __init__.
Class variables उन values के लिए हैं जो हर object सच में साझा करता है — settings, साझा reference data, counter। अगर हर object को अपनी copy चाहिए, तो उसे __init__ में रखें।
类变量用于所有对象真正共享的值 — 配置、共享参考数据、计数器。如果每个对象需要自己的一份,就放进 __init__。
4
Never use a mutable class variable (list, dict, set) unless sharing it is the whole point. Per-object lists belong in __init__ as self.x = [].
Mutable class variable (list, dict, set) कभी न रखें, जब तक साझा करना ही मक़सद न हो। हर object की list __init__ में self.x = [] के रूप में रहती है।
不要使用可变类变量(list、dict、set),除非共享本身就是目的。每个对象的列表应在 __init__ 中写成 self.x = []。
5
Change a class variable through the class: CoffeeShop.total_stores += 1, never self.total_stores += 1. The self form quietly makes a shadow and leaves the class variable unchanged.
Class variable को class के ज़रिए बदलें: CoffeeShop.total_stores += 1, कभी self.total_stores += 1 नहीं। self वाला रूप चुपचाप shadow बनाता है और class variable को नहीं बदलता।
通过类修改类变量:CoffeeShop.total_stores += 1,绝不要 self.total_stores += 1。self 写法会悄悄产生遮蔽,类变量保持不变。
6
Put @classmethod on the line above def, and name the first parameter cls. Without the decorator the method breaks (the first argument lands in the wrong place). cls is only a convention, but every Python programmer expects it.
def के ऊपर वाली line पर @classmethod रखें, और पहले parameter का नाम cls रखें। Decorator के बिना method टूट जाता है (पहला argument ग़लत जगह पहुँचता है)। cls सिर्फ़ परंपरा है, पर हर Python programmer यही उम्मीद करता है।
把 @classmethod 写在 def 上一行,并把第一个参数命名为 cls。 没有装饰器,方法就会出错(第一个参数落到错误的位置)。cls 只是约定,但每个 Python 程序员都期待这样写。
7
Inside a class method, build objects with cls(...), not ClassName(...). It keeps subclasses working — at no cost.
Class method के अंदर objects cls(...) से बनाएँ, ClassName(...) से नहीं। इससे subclasses सही चलती हैं — बिना किसी ख़र्च के।
在类方法里用 cls(...) 创建对象,而不是 ClassName(...)。这样子类也能正确工作 — 零成本。
8
Prefer alternate constructors (Employee.from_csv, date.today()) over helper functions outside the class. They keep the building logic next to the type they build.
Alternate constructors को प्राथमिकता दें (Employee.from_csv, date.today()), class के बाहर के helper functions की जगह। ये बनाने का logic उसी type के पास रखते हैं।
优先使用备用构造器(Employee.from_csv、date.today()),而不是类外的辅助函数。它们让构建逻辑紧挨着所构建的类型。
9
Read anywhere; write only through the class. store.company_name is fine for reading — Python falls back to the class. The moment you write store.company_name = "...", you have made a per-object attribute.
कहीं भी पढ़ें; लिखें सिर्फ़ class के ज़रिए। पढ़ने के लिए store.company_name ठीक है — Python class तक जाता है। जैसे ही आप store.company_name = "..." लिखते हैं, आपने हर-object वाला attribute बना दिया।
哪里都可以读;只通过类来写。 读取用 store.company_name 没问题 — Python 会退回到类上找。一旦你写 store.company_name = "...",就创建了一个对象自己的属性。
10
When in doubt, ask two questions. "Does this need one specific object?" → instance method. "Is this data the same for every object?" → class variable.
शक हो तो दो सवाल पूछें। "क्या इसे किसी एक ख़ास object की ज़रूरत है?" → instance method। "क्या यह data हर object के लिए एक जैसा है?" → class variable।
拿不准时,问两个问题。"这需要某一个特定对象吗?"→ 实例方法。"这份数据对所有对象都一样吗?"→ 类变量。

Quick Quiz — 8 Questionsछोटा Quiz — 8 सवाल小测验 — 8 道题

🏆 QuizPick an answer to see why.जवाब चुनें और कारण देखें।选一个答案,看看原因。
🎯
Key Takeawayमुख्य सीख关键要点

Instance methods get self and work on one object's data. Class variables live once on the class; reading through an object falls back to them, but writing through an object makes a shadow. Class methods get cls and work on the class — to build objects with cls(...), change shared data, or answer questions about all objects.

Instance methods को self मिलता है और वे एक object के data पर काम करते हैं। Class variables class पर एक बार रहते हैं; object के ज़रिए पढ़ने पर Python उन तक जाता है, पर object के ज़रिए लिखने से shadow बनता है। Class methods को cls मिलता है और वे class पर काम करते हैं — cls(...) से objects बनाने, साझा data बदलने, या सभी objects के बारे में सवालों के जवाब देने के लिए।

实例方法接收 self,处理某一个对象的数据。类变量在类上只存一份;通过对象读取会回退到它们,但通过对象写入会产生遮蔽。类方法接收 cls,作用于类本身 — 用 cls(...) 创建对象、修改共享数据,或回答关于所有对象的问题。

🐍 Try Python Yourself

Write, run and visualize Python step by step. No install needed.